Bug Summary

File:root/firefox-clang/obj-x86_64-pc-linux-gnu/toolkit/xre/./../../../toolkit/xre/nsXREDirProvider.cpp
Warning:line 298, column 7
Value stored to 'rv' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -O2 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name Unified_cpp_toolkit_xre1.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/toolkit/xre -fcoverage-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/toolkit/xre -resource-dir /usr/lib/llvm-23/lib/clang/23 -include /root/firefox-clang/config/gcc_hidden.h -include /root/firefox-clang/obj-x86_64-pc-linux-gnu/mozilla-config.h -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/stl_wrappers -D _GLIBCXX_ASSERTIONS=1 -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/system_wrappers -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D DEBUG=1 -D TELEMETRY_PING_FORMAT_VERSION=4 -D PROXY_PRINTING=1 -D USE_GLX_TEST -D MOZ_APP_NAME="firefox" -D MOZ_APP_BASENAME="Firefox" -D MOZ_APP_DISPLAYNAME="Nightly" -D MOZ_APP_VENDOR="Mozilla" -D MOZ_APP_VERSION="162.0a1" -D OS_TARGET="Linux" -D MOZ_WIDGET_TOOLKIT="gtk" -D MOZ_UPDATER -D MOZ_DISTRIBUTION_ID="org.mozilla" -D TARGET_OS_ABI="Linux_x86_64-gcc3" -D GRE_MILESTONE=162.0a1 -D MOZ_APP_VERSION_DISPLAY=162.0a1 -D APP_VERSION=162.0a1 -D APP_ID={ec8030f7-c20a-464f-9b0e-13a3a9e97384} -D MOZ_BUILD_APP_IS_BROWSER -D MAR_NSS -D TOPOBJDIR=/root/firefox-clang/obj-x86_64-pc-linux-gnu -D MOZ_HAS_MOZGLUE -D MOZILLA_INTERNAL_API -D IMPL_LIBXUL -D MOZ_SUPPORT_LEAKCHECKING -D STATIC_EXPORTABLE_JS_API -I /root/firefox-clang/toolkit/xre -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/toolkit/xre -I /root/firefox-clang/toolkit/components/remote -I /root/firefox-clang/widget -I /root/firefox-clang/widget/gtk -I /root/firefox-clang/toolkit/components/printingui -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/ipc/ipdl/_ipdlheaders -I /root/firefox-clang/ipc/chromium/src -I /root/firefox-clang/third_party/abseil-cpp -I /root/firefox-clang/other-licenses/nsis/Contrib/CityHash/cityhash -I /root/firefox-clang/toolkit/components/find -I /root/firefox-clang/toolkit/components/printingui/ipc -I /root/firefox-clang/toolkit/components/windowwatcher -I /root/firefox-clang/toolkit/mozapps/update/common -I /root/firefox-clang/toolkit/profile -I /root/firefox-clang/config -I /root/firefox-clang/dom/base -I /root/firefox-clang/dom/commandhandler -I /root/firefox-clang/dom/ipc -I /root/firefox-clang/dom/webbrowserpersist -I /root/firefox-clang/js/xpconnect/loader -I /root/firefox-clang/testing/gtest/mozilla -I /root/firefox-clang/third_party/sqlite3/ext -I /root/firefox-clang/toolkit/components/jsoncpp/include -I /root/firefox-clang/toolkit/crashreporter -I /root/firefox-clang/xpcom/build -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -I /usr/include/uuid -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I /usr/include/gtk-3.0/unix-print -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/cloudproviders -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I /usr/include/fribidi -I /usr/include/harfbuzz -I /usr/include/atk-1.0 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/glycin-2 -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/gio-unix-2.0 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/sysprof-6 -I /usr/include/pango-1.0 -I /usr/include/harfbuzz -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/cairo -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/pixman-1 -I /usr/include/sysprof-6 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/c++/16 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/x86_64-linux-gnu/c++/16 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/c++/16/backward -internal-isystem /usr/lib/llvm-23/lib/clang/23/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-error=pessimizing-move -Wno-error=large-by-value-copy=128 -Wno-error=implicit-int-float-conversion -Wno-error=thread-safety-analysis -Wno-error=tautological-type-limit-compare -Wno-invalid-offsetof -Wno-range-loop-analysis -Wno-deprecated-anon-enum-enum-conversion -Wno-deprecated-enum-enum-conversion -Wno-inline-new-delete -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-vla-cxx-extension -Wno-unknown-warning-option -Wno-character-conversion -std=gnu++20 -fdeprecated-macro -ferror-limit 19 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fno-rtti -fgnuc-version=4.2.1 -fno-implicit-modules -fskip-odr-check-in-gmf -fno-sized-deallocation -fno-aligned-allocation -fdiagnostics-absolute-paths -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -mllvm -dwarf-linkage-names=Abstract -faddrsig -fdwarf2-cfi-asm -o /tmp/scan-build-2026-11-12-001017-1011516-1 -x c++ Unified_cpp_toolkit_xre1.cpp
1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5#include "nsAppRunner.h"
6#include "nsXREDirProvider.h"
7#ifndef ANDROID
8# include "commonupdatedir.h"
9#endif
10
11#include "jsapi.h"
12#include "xpcpublic.h"
13#include "prprf.h"
14#include "prenv.h"
15
16#include "nsIAppStartup.h"
17#include "nsIFile.h"
18#include "nsIObserver.h"
19#include "nsIObserverService.h"
20#include "nsISimpleEnumerator.h"
21#include "nsIToolkitProfileService.h"
22#include "nsIXULRuntime.h"
23#include "commonupdatedir.h"
24
25#include "nsAppDirectoryServiceDefs.h"
26#include "nsDirectoryServiceDefs.h"
27#include "nsDirectoryServiceUtils.h"
28#include "nsXULAppAPI.h"
29#include "nsCategoryManagerUtils.h"
30
31#include "nsDependentString.h"
32#include "nsCOMArray.h"
33#include "nsArrayEnumerator.h"
34#include "nsEnumeratorUtils.h"
35#include "nsReadableUtils.h"
36
37#include "SpecialSystemDirectory.h"
38
39#include "mozilla/dom/ScriptSettings.h"
40
41#include "mozilla/AppShutdown.h"
42#include "mozilla/AutoRestore.h"
43#ifdef MOZ_BACKGROUNDTASKS1
44# include "mozilla/BackgroundTasks.h"
45#endif
46#include "mozilla/CmdLineAndEnvUtils.h"
47#include "mozilla/Components.h"
48#include "mozilla/DebugOnly.h"
49#include "mozilla/Services.h"
50#include "mozilla/Omnijar.h"
51#include "mozilla/Preferences.h"
52#include "mozilla/ProfilerLabels.h"
53#include "mozilla/glean/ToolkitProfileMetrics.h"
54#include "mozilla/glean/ToolkitXreMetrics.h"
55#include "mozilla/Try.h"
56#include "mozilla/Utf8.h"
57#include "mozilla/XREAppData.h"
58#include "mozilla/security/lockstore/ProfileKek.h"
59#include "nsPrintfCString.h"
60
61#ifdef MOZ_THUNDERBIRD
62# ifdef XP_MACOSX
63# include "MacApplicationDelegate.h"
64# endif
65# include "ScopedNSSTypes.h"
66# include "nsNSSComponent.h"
67#endif
68
69#include <stdlib.h>
70
71#ifdef XP_WIN
72# include <windows.h>
73# include <shlobj.h>
74# include "WinUtils.h"
75#endif
76#ifdef XP_MACOSX
77# ifdef NIGHTLY_BUILD1
78# include "AppGroupPath.h"
79# endif
80# include "nsILocalFileMac.h"
81// for chflags()
82# include <sys/stat.h>
83# include <unistd.h>
84#endif
85#ifdef XP_IOS
86# include "UIKitDirProvider.h"
87#endif
88
89#if defined(XP_MACOSX)
90# define APP_REGISTRY_NAME"appreg" "Application Registry"
91#elif defined(XP_WIN)
92# define APP_REGISTRY_NAME"appreg" "registry.dat"
93#else
94# define APP_REGISTRY_NAME"appreg" "appreg"
95#endif
96
97#define PREF_OVERRIDE_DIRNAME"preferences" "preferences"
98
99nsXREDirProvider* gDirServiceProvider = nullptr;
100nsIFile* gDataDirHomeLocal = nullptr;
101nsIFile* gDataDirHome = nullptr;
102constinit nsCOMPtr<nsIFile> gDataDirProfileLocal{};
103constinit nsCOMPtr<nsIFile> gDataDirProfile{};
104
105#if defined(MOZ_WIDGET_GTK1)
106nsXREDirProvider::legacyOrXDGHomeTelemetry gXdgTelemetry =
107 nsXREDirProvider::legacyOrXDGHomeTelemetry::empty;
108#endif // defined(MOZ_WIDGET_GTK)
109
110// These are required to allow nsXREDirProvider to be usable in xpcshell tests.
111// where gAppData is null.
112#if defined(XP_MACOSX) || defined(XP_UNIX1)
113static const char* GetAppName() {
114 if (gAppData) {
115 return gAppData->name;
116 }
117 return nullptr;
118}
119#endif
120
121#ifdef XP_MACOSX
122static const char* GetAppVendor() {
123 if (gAppData) {
124 return gAppData->vendor;
125 }
126 return nullptr;
127}
128#endif
129
130nsXREDirProvider::nsXREDirProvider() { gDirServiceProvider = this; }
131
132nsXREDirProvider::~nsXREDirProvider() {
133 gDirServiceProvider = nullptr;
134 gDataDirHomeLocal = nullptr;
135 gDataDirHome = nullptr;
136}
137
138already_AddRefed<nsXREDirProvider> nsXREDirProvider::GetSingleton() {
139 if (!gDirServiceProvider) {
140 new nsXREDirProvider(); // This sets gDirServiceProvider
141 }
142 return do_AddRef(gDirServiceProvider);
143}
144
145nsresult nsXREDirProvider::Initialize(nsIFile* aXULAppDir, nsIFile* aGREDir) {
146 NS_ENSURE_ARG(aXULAppDir)do { if ((__builtin_expect(!!(!(aXULAppDir)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aXULAppDir" ") failed",
nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp", 146)
; return NS_ERROR_INVALID_ARG; } } while (false)
;
147 NS_ENSURE_ARG(aGREDir)do { if ((__builtin_expect(!!(!(aGREDir)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aGREDir" ") failed", nullptr
, "./../../../toolkit/xre/nsXREDirProvider.cpp", 147); return
NS_ERROR_INVALID_ARG; } } while (false)
;
148
149 mXULAppDir = aXULAppDir;
150 mGREDir = aGREDir;
151 nsCOMPtr<nsIFile> binaryPath;
152 nsresult rv = XRE_GetBinaryPath(getter_AddRefs(binaryPath));
153 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 153); return rv; } } while (false)
;
154 return binaryPath->GetParent(getter_AddRefs(mGREBinDir));
155}
156
157nsresult nsXREDirProvider::SetProfile(nsIFile* aDir, nsIFile* aLocalDir) {
158 MOZ_ASSERT(aDir && aLocalDir, "We don't support no-profile apps!")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aDir && aLocalDir)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aDir && aLocalDir)))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("aDir && aLocalDir"
" (" "We don't support no-profile apps!" ")", "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 158); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aDir && aLocalDir"
") (" "We don't support no-profile apps!" ")"); do { MOZ_CrashSequence
(__null, 158); __attribute__((nomerge)) ::abort(); } while (false
); } } while (false)
;
159 MOZ_ASSERT(!mProfileDir && !mProfileLocalDir,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mProfileDir && !mProfileLocalDir)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(!mProfileDir && !mProfileLocalDir))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("!mProfileDir && !mProfileLocalDir"
" (" "You may only set the profile directories once" ")", "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 160); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mProfileDir && !mProfileLocalDir"
") (" "You may only set the profile directories once" ")"); do
{ MOZ_CrashSequence(__null, 160); __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
160 "You may only set the profile directories once")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mProfileDir && !mProfileLocalDir)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(!mProfileDir && !mProfileLocalDir))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("!mProfileDir && !mProfileLocalDir"
" (" "You may only set the profile directories once" ")", "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 160); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mProfileDir && !mProfileLocalDir"
") (" "You may only set the profile directories once" ")"); do
{ MOZ_CrashSequence(__null, 160); __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
161
162 nsresult rv = EnsureDirectoryExists(aDir);
163 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 163); return rv; } } while (false)
;
164
165 rv = EnsureDirectoryExists(aLocalDir);
166 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 166); return rv; } } while (false)
;
167
168#ifndef XP_WIN
169 nsAutoCString profilePath;
170 rv = aDir->GetNativePath(profilePath);
171 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 171); return rv; } } while (false)
;
172
173 nsAutoCString localProfilePath;
174 rv = aLocalDir->GetNativePath(localProfilePath);
175 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 175); return rv; } } while (false)
;
176
177 if (!mozilla::IsUtf8(profilePath) || !mozilla::IsUtf8(localProfilePath)) {
178 PR_fprintf(
179 PR_STDERRPR_GetSpecialFD(PR_StandardError),
180 "Error: The profile path is not valid UTF-8. Unable to continue.\n");
181 return NS_ERROR_FAILURE;
182 }
183#endif
184
185#ifdef XP_MACOSX
186 bool same;
187 if (NS_SUCCEEDED(aDir->Equals(aLocalDir, &same))((bool)(__builtin_expect(!!(!NS_FAILED_impl(aDir->Equals(aLocalDir
, &same))), 1)))
&& !same) {
188 // Ensure that the cache directory is not indexed by Spotlight
189 // (bug 718910). At least on OS X, the cache directory (under
190 // ~/Library/Caches/) is always the "local" user profile
191 // directory. This is confusing, since *both* user profile
192 // directories are "local" (they both exist under the user's
193 // home directory). But this usage dates back at least as far
194 // as the patch for bug 291033, where "local" seems to mean
195 // "suitable for temporary storage". Don't hide the cache
196 // directory if by some chance it and the "non-local" profile
197 // directory are the same -- there are bad side effects from
198 // hiding a profile directory under /Library/Application Support/
199 // (see bug 801883).
200 nsAutoCString cacheDir;
201 if (NS_SUCCEEDED(aLocalDir->GetNativePath(cacheDir))((bool)(__builtin_expect(!!(!NS_FAILED_impl(aLocalDir->GetNativePath
(cacheDir))), 1)))
) {
202 if (chflags(cacheDir.get(), UF_HIDDEN)) {
203 NS_WARNING("Failed to set Cache directory to HIDDEN.")NS_DebugBreak(NS_DEBUG_WARNING, "Failed to set Cache directory to HIDDEN."
, nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp", 203
)
;
204 }
205 }
206 }
207#endif
208
209 mProfileDir = aDir;
210 mProfileLocalDir = aLocalDir;
211 return NS_OK;
212}
213
214NS_IMPL_QUERY_INTERFACE(nsXREDirProvider, nsIDirectoryServiceProvider,nsresult nsXREDirProvider::QueryInterface(const nsIID& aIID
, void** aInstancePtr) { do { if (!(aInstancePtr)) { NS_DebugBreak
(NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!"
, "aInstancePtr", "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 216); MOZ_PretendNoReturn(); } } while (0); nsresult rv = NS_ERROR_FAILURE
; static_assert(4 > 0, "Need more arguments to NS_INTERFACE_TABLE"
); static const QITableEntry table[] = { {&mozilla::detail
::kImplementedIID<nsXREDirProvider, nsIDirectoryServiceProvider
>, int32_t( reinterpret_cast<char*>(static_cast<nsIDirectoryServiceProvider
*>((nsXREDirProvider*)0x1000)) - reinterpret_cast<char*
>((nsXREDirProvider*)0x1000))}, {&mozilla::detail::kImplementedIID
<nsXREDirProvider, nsIDirectoryServiceProvider2>, int32_t
( reinterpret_cast<char*>(static_cast<nsIDirectoryServiceProvider2
*>((nsXREDirProvider*)0x1000)) - reinterpret_cast<char*
>((nsXREDirProvider*)0x1000))}, {&mozilla::detail::kImplementedIID
<nsXREDirProvider, nsIXREDirProvider>, int32_t( reinterpret_cast
<char*>(static_cast<nsIXREDirProvider*>((nsXREDirProvider
*)0x1000)) - reinterpret_cast<char*>((nsXREDirProvider*
)0x1000))}, {&mozilla::detail::kImplementedIID<nsXREDirProvider
, nsIProfileStartup>, int32_t( reinterpret_cast<char*>
(static_cast<nsIProfileStartup*>((nsXREDirProvider*)0x1000
)) - reinterpret_cast<char*>((nsXREDirProvider*)0x1000)
)}, {&mozilla::detail::kImplementedIID<nsXREDirProvider
, nsISupports>, int32_t(reinterpret_cast<char*>(static_cast
<nsISupports*>( static_cast<nsIDirectoryServiceProvider
*>((nsXREDirProvider*)0x1000))) - reinterpret_cast<char
*>((nsXREDirProvider*)0x1000))}, { nullptr, 0 } } ; static_assert
(std::size(table) > 1, "need at least 1 interface"); rv = NS_TableDrivenQI
(static_cast<void*>(this), aIID, aInstancePtr, table); return
rv; }
215 nsIDirectoryServiceProvider2, nsIXREDirProvider,nsresult nsXREDirProvider::QueryInterface(const nsIID& aIID
, void** aInstancePtr) { do { if (!(aInstancePtr)) { NS_DebugBreak
(NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!"
, "aInstancePtr", "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 216); MOZ_PretendNoReturn(); } } while (0); nsresult rv = NS_ERROR_FAILURE
; static_assert(4 > 0, "Need more arguments to NS_INTERFACE_TABLE"
); static const QITableEntry table[] = { {&mozilla::detail
::kImplementedIID<nsXREDirProvider, nsIDirectoryServiceProvider
>, int32_t( reinterpret_cast<char*>(static_cast<nsIDirectoryServiceProvider
*>((nsXREDirProvider*)0x1000)) - reinterpret_cast<char*
>((nsXREDirProvider*)0x1000))}, {&mozilla::detail::kImplementedIID
<nsXREDirProvider, nsIDirectoryServiceProvider2>, int32_t
( reinterpret_cast<char*>(static_cast<nsIDirectoryServiceProvider2
*>((nsXREDirProvider*)0x1000)) - reinterpret_cast<char*
>((nsXREDirProvider*)0x1000))}, {&mozilla::detail::kImplementedIID
<nsXREDirProvider, nsIXREDirProvider>, int32_t( reinterpret_cast
<char*>(static_cast<nsIXREDirProvider*>((nsXREDirProvider
*)0x1000)) - reinterpret_cast<char*>((nsXREDirProvider*
)0x1000))}, {&mozilla::detail::kImplementedIID<nsXREDirProvider
, nsIProfileStartup>, int32_t( reinterpret_cast<char*>
(static_cast<nsIProfileStartup*>((nsXREDirProvider*)0x1000
)) - reinterpret_cast<char*>((nsXREDirProvider*)0x1000)
)}, {&mozilla::detail::kImplementedIID<nsXREDirProvider
, nsISupports>, int32_t(reinterpret_cast<char*>(static_cast
<nsISupports*>( static_cast<nsIDirectoryServiceProvider
*>((nsXREDirProvider*)0x1000))) - reinterpret_cast<char
*>((nsXREDirProvider*)0x1000))}, { nullptr, 0 } } ; static_assert
(std::size(table) > 1, "need at least 1 interface"); rv = NS_TableDrivenQI
(static_cast<void*>(this), aIID, aInstancePtr, table); return
rv; }
216 nsIProfileStartup)nsresult nsXREDirProvider::QueryInterface(const nsIID& aIID
, void** aInstancePtr) { do { if (!(aInstancePtr)) { NS_DebugBreak
(NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!"
, "aInstancePtr", "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 216); MOZ_PretendNoReturn(); } } while (0); nsresult rv = NS_ERROR_FAILURE
; static_assert(4 > 0, "Need more arguments to NS_INTERFACE_TABLE"
); static const QITableEntry table[] = { {&mozilla::detail
::kImplementedIID<nsXREDirProvider, nsIDirectoryServiceProvider
>, int32_t( reinterpret_cast<char*>(static_cast<nsIDirectoryServiceProvider
*>((nsXREDirProvider*)0x1000)) - reinterpret_cast<char*
>((nsXREDirProvider*)0x1000))}, {&mozilla::detail::kImplementedIID
<nsXREDirProvider, nsIDirectoryServiceProvider2>, int32_t
( reinterpret_cast<char*>(static_cast<nsIDirectoryServiceProvider2
*>((nsXREDirProvider*)0x1000)) - reinterpret_cast<char*
>((nsXREDirProvider*)0x1000))}, {&mozilla::detail::kImplementedIID
<nsXREDirProvider, nsIXREDirProvider>, int32_t( reinterpret_cast
<char*>(static_cast<nsIXREDirProvider*>((nsXREDirProvider
*)0x1000)) - reinterpret_cast<char*>((nsXREDirProvider*
)0x1000))}, {&mozilla::detail::kImplementedIID<nsXREDirProvider
, nsIProfileStartup>, int32_t( reinterpret_cast<char*>
(static_cast<nsIProfileStartup*>((nsXREDirProvider*)0x1000
)) - reinterpret_cast<char*>((nsXREDirProvider*)0x1000)
)}, {&mozilla::detail::kImplementedIID<nsXREDirProvider
, nsISupports>, int32_t(reinterpret_cast<char*>(static_cast
<nsISupports*>( static_cast<nsIDirectoryServiceProvider
*>((nsXREDirProvider*)0x1000))) - reinterpret_cast<char
*>((nsXREDirProvider*)0x1000))}, { nullptr, 0 } } ; static_assert
(std::size(table) > 1, "need at least 1 interface"); rv = NS_TableDrivenQI
(static_cast<void*>(this), aIID, aInstancePtr, table); return
rv; }
217
218NS_IMETHODIMP_(MozExternalRefCountType)MozExternalRefCountType
219nsXREDirProvider::AddRef() { return 1; }
220
221NS_IMETHODIMP_(MozExternalRefCountType)MozExternalRefCountType
222nsXREDirProvider::Release() { return 0; }
223
224nsresult nsXREDirProvider::GetUserProfilesRootDir(nsIFile** aResult) {
225 nsCOMPtr<nsIFile> file;
226 nsresult rv = NS_OK;
227#if defined(XP_MACOSX) && defined(NIGHTLY_BUILD1)
228 const char* appGroup = PR_GetEnv("MOZ_APP_GROUP");
229 if (appGroup && *appGroup && strcmp(appGroup, "0") != 0) {
230 nsCOMPtr<nsIFile> group;
231 rv = GetAppGroupContainerBase(getter_AddRefs(group));
232 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && group) {
233 rv = group->AppendNative("Library"_ns);
234 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 234); return rv; } } while (false)
;
235 rv = group->AppendNative("Application Support"_ns);
236 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 236); return rv; } } while (false)
;
237 rv = group->AppendNative("Profiles"_ns);
238 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 238); return rv; } } while (false)
;
239 file = group;
240 }
241 }
242#endif
243 if (!file) {
244 rv = GetUserDataDirectory(getter_AddRefs(file), false);
245 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 245); return rv; } } while (false)
;
246#if !defined(XP_UNIX1) || defined(XP_MACOSX)
247 rv = file->AppendNative("Profiles"_ns);
248#endif
249 // We must create the profile directory here if it does not exist.
250 nsresult tmp = EnsureDirectoryExists(file);
251 if (NS_FAILED(tmp)((bool)(__builtin_expect(!!(NS_FAILED_impl(tmp)), 0)))) {
252 rv = tmp;
253 }
254
255#if defined(MOZ_WIDGET_GTK1)
256 switch (gXdgTelemetry) {
257 case legacyOrXDGHomeTelemetry::legacyExists:
258 mozilla::glean::profiles::creation_place.Get("legacy_existing"_ns)
259 .Add(1);
260 break;
261 case legacyOrXDGHomeTelemetry::legacyForced:
262 mozilla::glean::profiles::creation_place.Get("legacy_forced"_ns).Add(1);
263 break;
264 case legacyOrXDGHomeTelemetry::xdgDefault:
265 mozilla::glean::profiles::creation_place.Get("xdg_default"_ns).Add(1);
266 break;
267 case legacyOrXDGHomeTelemetry::xdgConfigHome:
268 mozilla::glean::profiles::creation_place.Get("xdg_config"_ns).Add(1);
269 break;
270 default: {
271 nsAutoCString nativePath;
272 nsresult rv_conv = file->GetNativePath(nativePath);
273 if (NS_SUCCEEDED(rv_conv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv_conv)), 1)))) {
274 NS_WARNING(nsPrintfCString(NS_DebugBreak(NS_DEBUG_WARNING, nsPrintfCString( "Recording no telemetry value with profile path %s"
, nativePath.get()) .get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 277)
275 "Recording no telemetry value with profile path %s",NS_DebugBreak(NS_DEBUG_WARNING, nsPrintfCString( "Recording no telemetry value with profile path %s"
, nativePath.get()) .get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 277)
276 nativePath.get())NS_DebugBreak(NS_DEBUG_WARNING, nsPrintfCString( "Recording no telemetry value with profile path %s"
, nativePath.get()) .get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 277)
277 .get())NS_DebugBreak(NS_DEBUG_WARNING, nsPrintfCString( "Recording no telemetry value with profile path %s"
, nativePath.get()) .get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 277)
;
278 }
279 } break;
280 }
281#endif // defined(MOZ_WIDGET_GTK)
282 }
283 file.swap(*aResult);
284 return rv;
285}
286
287nsresult nsXREDirProvider::GetUserProfilesLocalDir(nsIFile** aResult) {
288 nsCOMPtr<nsIFile> file;
289 nsresult rv = GetUserDataDirectory(getter_AddRefs(file), true);
290
291 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
292#if !defined(XP_UNIX1) || defined(XP_MACOSX)
293 rv = file->AppendNative("Profiles"_ns);
294#endif
295 // We must create the profile directory here if it does not exist.
296 nsresult tmp = EnsureDirectoryExists(file);
297 if (NS_FAILED(tmp)((bool)(__builtin_expect(!!(NS_FAILED_impl(tmp)), 0)))) {
298 rv = tmp;
Value stored to 'rv' is never read
299 }
300 }
301 file.swap(*aResult);
302 return NS_OK;
303}
304
305#ifdef MOZ_BACKGROUNDTASKS1
306nsresult nsXREDirProvider::GetBackgroundTasksProfilesRootDir(
307 nsIFile** aResult) {
308 nsCOMPtr<nsIFile> file;
309 nsresult rv = GetUserDataDirectory(getter_AddRefs(file), false);
310
311 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
312# if !defined(XP_UNIX1) || defined(XP_MACOSX)
313 // Sibling to regular user "Profiles" directory.
314 rv = file->AppendNative("Background Tasks Profiles"_ns);
315# endif
316 // We must create the directory here if it does not exist.
317 nsresult tmp = EnsureDirectoryExists(file);
318 if (NS_FAILED(tmp)((bool)(__builtin_expect(!!(NS_FAILED_impl(tmp)), 0)))) {
319 rv = tmp;
320 }
321 }
322 file.swap(*aResult);
323 return rv;
324}
325#endif
326
327#if defined(XP_UNIX1) || defined(XP_MACOSX)
328/**
329 * Get the directory that is the parent of the system-wide directories
330 * for extensions and native manifests.
331 *
332 * On OSX this is /Library/Application Support/Mozilla
333 * On Linux this is /usr/{lib,lib64}/mozilla
334 * (for 32- and 64-bit systems respsectively)
335 */
336static nsresult GetSystemParentDirectory(nsIFile** aFile) {
337 nsresult rv;
338 nsCOMPtr<nsIFile> localDir;
339# if defined(XP_MACOSX)
340 rv = GetOSXFolderType(kOnSystemDisk, kApplicationSupportFolderType,
341 getter_AddRefs(localDir));
342 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
343 rv = localDir->AppendNative("Mozilla"_ns);
344 }
345# else
346 constexpr auto dirname =
347# ifdef HAVE_USR_LIB64_DIR
348 "/usr/lib64/mozilla"_ns
349# elif defined(__OpenBSD__) || defined(__FreeBSD__)
350 "/usr/local/lib/mozilla"_ns
351# else
352 "/usr/lib/mozilla"_ns
353# endif
354 ;
355 rv = NS_NewNativeLocalFile(dirname, getter_AddRefs(localDir));
356# endif
357
358 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
359 localDir.forget(aFile);
360 }
361 return rv;
362}
363#endif
364
365NS_IMETHODIMPnsresult
366nsXREDirProvider::GetFile(const char* aProperty, bool* aPersistent,
367 nsIFile** aFile) {
368 *aPersistent = true;
369 nsresult rv = NS_ERROR_FAILURE;
370
371 nsCOMPtr<nsIFile> file;
372
373 if (!strcmp(aProperty, NS_APP_USER_PROFILE_LOCAL_50_DIR"ProfLD") ||
374 !strcmp(aProperty, NS_APP_PROFILE_LOCAL_DIR_STARTUP"ProfLDS")) {
375 if (mProfileLocalDir) {
376 rv = mProfileLocalDir->Clone(getter_AddRefs(file));
377 } else {
378 // Profile directories are only set up in the parent process.
379 // We don't expect every caller to check if they are in the right process,
380 // so fail immediately to avoid warning spam.
381 NS_WARNING_ASSERTION(!XRE_IsParentProcess(),do { if (!(!XRE_IsParentProcess())) { NS_DebugBreak(NS_DEBUG_WARNING
, "tried to get profile in parent too early", "!XRE_IsParentProcess()"
, "./../../../toolkit/xre/nsXREDirProvider.cpp", 382); } } while
(false)
382 "tried to get profile in parent too early")do { if (!(!XRE_IsParentProcess())) { NS_DebugBreak(NS_DEBUG_WARNING
, "tried to get profile in parent too early", "!XRE_IsParentProcess()"
, "./../../../toolkit/xre/nsXREDirProvider.cpp", 382); } } while
(false)
;
383 return NS_ERROR_FAILURE;
384 }
385 } else if (!strcmp(aProperty, NS_APP_USER_PROFILE_50_DIR"ProfD") ||
386 !strcmp(aProperty, NS_APP_PROFILE_DIR_STARTUP"ProfDS")) {
387 rv = GetProfileStartupDir(getter_AddRefs(file));
388 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
389 return rv;
390 }
391 } else if (!strcmp(aProperty, NS_GRE_DIR"GreD")) {
392 // On Android, internal files are inside the APK, a zip file, so this
393 // folder doesn't really make sense.
394#if !defined(MOZ_WIDGET_ANDROID)
395 rv = mGREDir->Clone(getter_AddRefs(file));
396#endif // !defined(MOZ_WIDGET_ANDROID)
397 } else if (!strcmp(aProperty, NS_GRE_BIN_DIR"GreBinD")) {
398 rv = mGREBinDir->Clone(getter_AddRefs(file));
399 } else if (!strcmp(aProperty, NS_OS_CURRENT_PROCESS_DIR"CurProcD") ||
400 !strcmp(aProperty, NS_APP_INSTALL_CLEANUP_DIR"XPIClnupD")) {
401 rv = GetAppDir()->Clone(getter_AddRefs(file));
402 } else if (!strcmp(aProperty, NS_APP_PREF_DEFAULTS_50_DIR"PrfDef")) {
403 // Same as NS_GRE_DIR
404#if !defined(MOZ_WIDGET_ANDROID)
405 // return the GRE default prefs directory here, and the app default prefs
406 // directory (if applicable) in NS_APP_PREFS_DEFAULTS_DIR_LIST.
407 rv = mGREDir->Clone(getter_AddRefs(file));
408 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 408); return rv; } } while (false)
;
409 rv = file->AppendNative("defaults"_ns);
410 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 410); return rv; } } while (false)
;
411 rv = file->AppendNative("pref"_ns);
412#endif // !defined(MOZ_WIDGET_ANDROID)
413 } else if (!strcmp(aProperty, NS_APP_APPLICATION_REGISTRY_DIR"AppRegD") ||
414 !strcmp(aProperty, XRE_USER_APP_DATA_DIR"UAppData")) {
415 rv = GetUserAppDataDirectory(getter_AddRefs(file));
416 }
417#if defined(XP_UNIX1) || defined(XP_MACOSX)
418 else if (!strcmp(aProperty, XRE_SYS_NATIVE_MANIFESTS"XRESysNativeManifests")) {
419 rv = ::GetSystemParentDirectory(getter_AddRefs(file));
420 } else if (!strcmp(aProperty, XRE_USER_NATIVE_MANIFESTS"XREUserNativeManifests")) {
421 // Keep forcing the legacy path for compatibility
422 rv = GetUserDataDirectoryHome(getter_AddRefs(file), /* aLocal */ false,
423 /* aForceLegacy */ true);
424 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 424); return rv; } } while (false)
;
425# if defined(XP_MACOSX)
426 rv = file->AppendNative("Mozilla"_ns);
427# else // defined(XP_MACOSX)
428 rv = file->AppendNative(".mozilla"_ns);
429# endif // defined(XP_MACOSX)
430 }
431#endif // defined(XP_UNIX) || defined(XP_MACOSX)
432 else if (!strcmp(aProperty, XRE_UPDATE_ROOT_DIR"UpdRootD")) {
433 rv = GetUpdateRootDir(getter_AddRefs(file));
434 } else if (!strcmp(aProperty, XRE_OLD_UPDATE_ROOT_DIR"OldUpdRootD")) {
435 rv = GetUpdateRootDir(getter_AddRefs(file), true);
436 } else if (!strcmp(aProperty, NS_APP_APPLICATION_REGISTRY_FILE"AppRegF")) {
437 rv = GetUserAppDataDirectory(getter_AddRefs(file));
438 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 438); return rv; } } while (false)
;
439 rv = file->AppendNative(nsLiteralCString(APP_REGISTRY_NAME"appreg"));
440 } else if (!strcmp(aProperty, NS_APP_USER_PROFILES_ROOT_DIR"DefProfRt")) {
441 rv = GetUserProfilesRootDir(getter_AddRefs(file));
442 } else if (!strcmp(aProperty, NS_APP_USER_PROFILES_LOCAL_ROOT_DIR"DefProfLRt")) {
443 rv = GetUserProfilesLocalDir(getter_AddRefs(file));
444 } else if (!strcmp(aProperty, XRE_EXECUTABLE_FILE"XREExeF")) {
445 rv = XRE_GetBinaryPath(getter_AddRefs(file));
446 }
447#if defined(XP_UNIX1) || defined(XP_MACOSX)
448 else if (!strcmp(aProperty, XRE_SYS_LOCAL_EXTENSION_PARENT_DIR"XRESysLExtPD")) {
449# ifdef ENABLE_SYSTEM_EXTENSION_DIRS1
450 rv = GetSystemExtensionsDirectory(getter_AddRefs(file));
451# endif
452 }
453#endif // defined(XP_UNIX) || defined(XP_MACOSX)
454#if defined(XP_UNIX1) && !defined(XP_MACOSX)
455 else if (!strcmp(aProperty, XRE_SYS_SHARE_EXTENSION_PARENT_DIR"XRESysSExtPD")) {
456# ifdef ENABLE_SYSTEM_EXTENSION_DIRS1
457# if defined(__OpenBSD__) || defined(__FreeBSD__)
458 static const char* const sysLExtDir = "/usr/local/share/mozilla/extensions";
459# else
460 static const char* const sysLExtDir = "/usr/share/mozilla/extensions";
461# endif
462 rv = NS_NewNativeLocalFile(nsDependentCString(sysLExtDir),
463 getter_AddRefs(file));
464# endif
465 }
466#endif // defined(XP_UNIX) && !defined(XP_MACOSX)
467 else if (!strcmp(aProperty, XRE_USER_SYS_EXTENSION_DIR"XREUSysExt")) {
468#ifdef ENABLE_SYSTEM_EXTENSION_DIRS1
469 rv = GetSysUserExtensionsDirectory(getter_AddRefs(file));
470#endif
471 } else if (!strcmp(aProperty, XRE_USER_RUNTIME_DIR"XREUserRunTimeDir")) {
472#if defined(XP_UNIX1)
473 nsPrintfCString path("/run/user/%d/%s/", getuid(), GetAppName());
474 ToLowerCase(path);
475 rv = NS_NewNativeLocalFile(path, getter_AddRefs(file));
476#endif
477 } else if (!strcmp(aProperty, XRE_APP_DISTRIBUTION_DIR"XREAppDist")) {
478 bool persistent = false;
479 rv = GetFile(NS_GRE_DIR"GreD", &persistent, getter_AddRefs(file));
480 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 480); return rv; } } while (false)
;
481 rv = file->AppendNative("distribution"_ns);
482 } else if (!strcmp(aProperty, XRE_APP_FEATURES_DIR"XREAppFeat")) {
483 rv = GetAppDir()->Clone(getter_AddRefs(file));
484 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 484); return rv; } } while (false)
;
485 rv = file->AppendNative("features"_ns);
486 } else if (!strcmp(aProperty, XRE_ADDON_APP_DIR"XREAddonAppDir")) {
487 nsCOMPtr<nsIDirectoryServiceProvider> dirsvc(
488 do_GetService("@mozilla.org/file/directory_service;1", &rv));
489 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 489); return rv; } } while (false)
;
490 bool unused;
491 rv = dirsvc->GetFile("XCurProcD", &unused, getter_AddRefs(file));
492 } else if (!strcmp(aProperty, NS_APP_USER_CHROME_DIR"UChrm")) {
493 // It isn't clear why this uses GetProfileStartupDir instead of
494 // GetProfileDir. It could theoretically matter in a non-main
495 // process where some other directory provider has defined
496 // NS_APP_USER_PROFILE_50_DIR. In that scenario, using
497 // GetProfileStartupDir means this will fail instead of succeed.
498 rv = GetProfileStartupDir(getter_AddRefs(file));
499 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
500 return rv;
501 }
502 rv = file->AppendNative("chrome"_ns);
503 } else if (!strcmp(aProperty, NS_APP_PREFS_50_DIR"PrefD")) {
504 rv = GetProfileDir(getter_AddRefs(file));
505 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
506 return rv;
507 }
508 } else if (!strcmp(aProperty, NS_APP_PREFS_50_FILE"PrefF")) {
509 rv = GetProfileDir(getter_AddRefs(file));
510 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
511 return rv;
512 }
513 rv = file->AppendNative("prefs.js"_ns);
514 } else if (!strcmp(aProperty, NS_APP_PREFS_OVERRIDE_DIR"PrefDOverride")) {
515 rv = GetProfileDir(getter_AddRefs(file));
516 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
517 return rv;
518 }
519 rv = file->AppendNative(nsLiteralCString(PREF_OVERRIDE_DIRNAME"preferences"));
520 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 520); return rv; } } while (false)
;
521 rv = EnsureDirectoryExists(file);
522 } else {
523 // We don't know anything about this property. Fail without warning, because
524 // otherwise we'll get too much warning spam due to
525 // nsDirectoryService::Get() trying everything it gets with every provider.
526 return NS_ERROR_FAILURE;
527 }
528
529 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 529); return rv; } } while (false)
;
530 NS_ENSURE_TRUE(file, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(file)), 0))) { NS_DebugBreak(
NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "file" ") failed", nullptr
, "./../../../toolkit/xre/nsXREDirProvider.cpp", 530); return
NS_ERROR_FAILURE; } } while (false)
;
531
532 file.forget(aFile);
533 return NS_OK;
534}
535
536static void LoadDirIntoArray(nsIFile* dir, const char* const* aAppendList,
537 nsCOMArray<nsIFile>& aDirectories) {
538 if (!dir) return;
539
540 nsCOMPtr<nsIFile> subdir;
541 dir->Clone(getter_AddRefs(subdir));
542 if (!subdir) return;
543
544 for (const char* const* a = aAppendList; *a; ++a) {
545 subdir->AppendNative(nsDependentCString(*a));
546 }
547
548 bool exists;
549 if (NS_SUCCEEDED(subdir->Exists(&exists))((bool)(__builtin_expect(!!(!NS_FAILED_impl(subdir->Exists
(&exists))), 1)))
&& exists) {
550 aDirectories.AppendObject(subdir);
551 }
552}
553
554static const char* const kAppendPrefDir[] = {"defaults", "preferences",
555 nullptr};
556#ifdef MOZ_BACKGROUNDTASKS1
557static const char* const kAppendBackgroundTasksPrefDir[] = {
558 "defaults", "backgroundtasks", nullptr};
559#endif
560
561NS_IMETHODIMPnsresult
562nsXREDirProvider::GetFiles(const char* aProperty,
563 nsISimpleEnumerator** aResult) {
564 nsresult rv = NS_ERROR_FAILURE;
565 *aResult = nullptr;
566
567 if (!strcmp(aProperty, NS_APP_PREFS_DEFAULTS_DIR_LIST"PrefDL")) {
568 nsCOMArray<nsIFile> directories;
569
570 LoadDirIntoArray(mXULAppDir, kAppendPrefDir, directories);
571#ifdef MOZ_BACKGROUNDTASKS1
572 if (mozilla::BackgroundTasks::IsBackgroundTaskMode()) {
573 LoadDirIntoArray(mGREDir, kAppendBackgroundTasksPrefDir, directories);
574 LoadDirIntoArray(mXULAppDir, kAppendBackgroundTasksPrefDir, directories);
575 }
576#endif
577
578 rv = NS_NewArrayEnumerator(aResult, directories, NS_GET_IID(nsIFile)(nsIFile::kIID));
579 } else if (!strcmp(aProperty, NS_APP_CHROME_DIR_LIST"AChromDL")) {
580 // NS_APP_CHROME_DIR_LIST is only used to get default (native) icons
581 // for OS window decoration.
582
583 static const char* const kAppendChromeDir[] = {"chrome", nullptr};
584 nsCOMArray<nsIFile> directories;
585 LoadDirIntoArray(mXULAppDir, kAppendChromeDir, directories);
586
587 rv = NS_NewArrayEnumerator(aResult, directories, NS_GET_IID(nsIFile)(nsIFile::kIID));
588 }
589 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 589); return rv; } } while (false)
;
590
591 return NS_SUCCESS_AGGREGATE_RESULT;
592}
593
594NS_IMETHODIMPnsresult
595nsXREDirProvider::GetDirectory(nsIFile** aResult) {
596 NS_ENSURE_TRUE(mProfileDir, NS_ERROR_NOT_INITIALIZED)do { if ((__builtin_expect(!!(!(mProfileDir)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "mProfileDir" ") failed"
, nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp", 596
); return NS_ERROR_NOT_INITIALIZED; } } while (false)
;
597 return mProfileDir->Clone(aResult);
598}
599
600void nsXREDirProvider::InitializeUserPrefs() {
601 if (!mPrefsInitialized) {
602 mozilla::Preferences::InitializeUserPrefs();
603 }
604}
605
606void nsXREDirProvider::FinishInitializingUserPrefs() {
607 if (!mPrefsInitialized) {
608 mozilla::Preferences::FinishInitializingUserPrefs();
609 mPrefsInitialized = true;
610 }
611}
612
613NS_IMETHODIMPnsresult
614nsXREDirProvider::DoStartup() {
615 nsresult rv;
616
617 if (!mAppStarted) {
618 nsCOMPtr<nsIObserverService> obsSvc =
619 mozilla::services::GetObserverService();
620 if (!obsSvc) return NS_ERROR_FAILURE;
621
622 mAppStarted = true;
623
624 /*
625 Make sure we've setup prefs before profile-do-change to be able to use
626 them to track crashes and because we want to begin crash tracking before
627 other code run from this notification since they may cause crashes.
628 */
629 MOZ_ASSERT(mPrefsInitialized)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mPrefsInitialized)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mPrefsInitialized))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("mPrefsInitialized"
, "./../../../toolkit/xre/nsXREDirProvider.cpp", 629); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "mPrefsInitialized" ")"); do { MOZ_CrashSequence
(__null, 629); __attribute__((nomerge)) ::abort(); } while (false
); } } while (false)
;
630
631 bool safeModeNecessary = false;
632 nsCOMPtr<nsIAppStartup> appStartup(
633 mozilla::components::AppStartup::Service());
634 if (appStartup) {
635 rv = appStartup->TrackStartupCrashBegin(&safeModeNecessary);
636 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) && rv != NS_ERROR_NOT_AVAILABLE)
637 NS_WARNING("Error while beginning startup crash tracking")NS_DebugBreak(NS_DEBUG_WARNING, "Error while beginning startup crash tracking"
, nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp", 637
)
;
638
639 if (!gSafeMode && safeModeNecessary) {
640 appStartup->RestartInSafeMode(nsIAppStartup::eForceQuit);
641 return NS_OK;
642 }
643 }
644
645 bool isBackgroundTask = false;
646#ifdef MOZ_BACKGROUNDTASKS1
647 isBackgroundTask = mozilla::BackgroundTasks::IsBackgroundTaskMode();
648#endif
649 // Ahead of profile-do-change, whose observers start opening profile
650 // databases that cannot be read until the profile KEK is unlocked.
651 if (XRE_IsParentProcess() && !isBackgroundTask &&
652 !mozilla::security::lockstore::SyncProfileKekAtStartup()) {
653 if (appStartup) {
654 appStartup->Quit(nsIAppStartup::eForceQuit, 0);
655 }
656 return NS_OK;
657 }
658
659 static const char16_t kStartup[] = {'s', 't', 'a', 'r',
660 't', 'u', 'p', '\0'};
661 obsSvc->NotifyObservers(nullptr, "profile-do-change", kStartup);
662
663 // Initialize the Enterprise Policies service in the parent process
664 // In the content process it's loaded on demand when needed
665 if (XRE_IsParentProcess()) {
666 nsCOMPtr<nsIObserver> policies(
667 do_GetService("@mozilla.org/enterprisepolicies;1"));
668 if (policies) {
669 policies->Observe(nullptr, "policies-startup", nullptr);
670 }
671 }
672
673#ifdef MOZ_THUNDERBIRD
674 bool bgtaskMode = false;
675# ifdef MOZ_BACKGROUNDTASKS1
676 bgtaskMode = mozilla::BackgroundTasks::IsBackgroundTaskMode();
677# endif
678 if (!bgtaskMode &&
679 mozilla::Preferences::GetBool(
680 "security.prompt_for_master_password_on_startup", false)) {
681# ifdef XP_MACOSX
682 // Ensure the application is initialized before the prompt is triggered.
683 // Note: calling InitializeMacApp more than once does nothing.
684 InitializeMacApp();
685# endif
686 // Prompt for the master password prior to opening application windows,
687 // to avoid the race that triggers multiple prompts (see bug 177175).
688 // We use this code until we have a better solution, possibly as
689 // described in bug 177175 comment 384.
690 // Ensure NSS is initialized; it may not be this early in startup.
691 nsCOMPtr<nsINSSComponent> nssComponent(
692 do_GetService(NS_NSSCOMPONENT_CID));
693 mozilla::UniquePK11SlotInfo slot(PK11_GetInternalKeySlot());
694 if (slot) {
695 (void)PK11_Authenticate(slot.get(), true, nullptr);
696 }
697 }
698#endif
699
700 bool initExtensionManager =
701#ifdef MOZ_BACKGROUNDTASKS1
702 !mozilla::BackgroundTasks::IsBackgroundTaskMode();
703#else
704 true;
705#endif
706 if (initExtensionManager) {
707 // Init the Extension Manager
708 nsCOMPtr<nsIObserver> em =
709 do_GetService("@mozilla.org/addons/integration;1");
710 if (em) {
711 em->Observe(nullptr, "addons-startup", nullptr);
712 } else {
713 NS_WARNING("Failed to create Addons Manager.")NS_DebugBreak(NS_DEBUG_WARNING, "Failed to create Addons Manager."
, nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp", 713
)
;
714 }
715 }
716
717 obsSvc->NotifyObservers(nullptr, "profile-after-change", kStartup);
718
719 // Any component that has registered for the profile-after-change category
720 // should also be created at this time.
721 (void)NS_CreateServicesFromCategory("profile-after-change", nullptr,
722 "profile-after-change");
723
724 if (gSafeMode && safeModeNecessary) {
725 static const char16_t kCrashed[] = {'c', 'r', 'a', 's',
726 'h', 'e', 'd', '\0'};
727 obsSvc->NotifyObservers(nullptr, "safemode-forced", kCrashed);
728 }
729
730 // 1 = Regular mode, 2 = Safe mode, 3 = Safe mode forced
731 int mode = 1;
732 if (gSafeMode) {
733 if (safeModeNecessary)
734 mode = 3;
735 else
736 mode = 2;
737 }
738 mozilla::glean::gecko::safe_mode_usage.AccumulateSingleSample(mode);
739
740 obsSvc->NotifyObservers(nullptr, "profile-initial-state", nullptr);
741 }
742 return NS_OK;
743}
744
745void nsXREDirProvider::DoShutdown() {
746 AUTO_PROFILER_LABEL("nsXREDirProvider::DoShutdown", OTHER)mozilla::AutoProfilerLabel raiiObject746( "nsXREDirProvider::DoShutdown"
, nullptr, JS::ProfilingCategoryPair::OTHER)
;
747
748 if (mAppStarted) {
749 mozilla::AppShutdown::AdvanceShutdownPhase(
750 mozilla::ShutdownPhase::AppShutdownNetTeardown, nullptr);
751 mozilla::AppShutdown::AdvanceShutdownPhase(
752 mozilla::ShutdownPhase::AppShutdownTeardown, nullptr);
753
754#ifdef DEBUG1
755 // Not having this causes large intermittent leaks. See bug 1340425.
756 if (JSContext* cx = mozilla::dom::danger::GetJSContext()) {
757 JS_GC(cx);
758 }
759#endif
760
761 mozilla::AppShutdown::AdvanceShutdownPhase(
762 mozilla::ShutdownPhase::AppShutdown, nullptr);
763 mozilla::AppShutdown::AdvanceShutdownPhase(
764 mozilla::ShutdownPhase::AppShutdownQM, nullptr);
765 mozilla::AppShutdown::AdvanceShutdownPhase(
766 mozilla::ShutdownPhase::AppShutdownTelemetry, nullptr);
767 mAppStarted = false;
768 }
769
770 gDataDirProfileLocal = nullptr;
771 gDataDirProfile = nullptr;
772}
773
774#ifdef XP_WIN
775static nsresult GetShellFolderPath(KNOWNFOLDERID folder, nsAString& _retval) {
776 DWORD flags = KF_FLAG_SIMPLE_IDLIST | KF_FLAG_DONT_VERIFY | KF_FLAG_NO_ALIAS;
777 PWSTR path = nullptr;
778
779 if (!SUCCEEDED(SHGetKnownFolderPath(folder, flags, NULL__null, &path))) {
780 return NS_ERROR_NOT_AVAILABLE;
781 }
782
783 _retval = nsDependentString(path);
784 CoTaskMemFree(path);
785 return NS_OK;
786}
787
788/**
789 * Provides a fallback for getting the path to APPDATA or LOCALAPPDATA by
790 * querying the registry when the call to SHGetSpecialFolderLocation or
791 * SHGetPathFromIDListW is unable to provide these paths (Bug 513958).
792 */
793static nsresult GetRegWindowsAppDataFolder(bool aLocal, nsAString& _retval) {
794 HKEY key;
795 LPCWSTR keyName =
796 L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
797 DWORD res = ::RegOpenKeyExW(HKEY_CURRENT_USER, keyName, 0, KEY_READ, &key);
798 if (res != ERROR_SUCCESS) {
799 _retval.SetLength(0);
800 return NS_ERROR_NOT_AVAILABLE;
801 }
802
803 DWORD type, size;
804 res = RegQueryValueExW(key, (aLocal ? L"Local AppData" : L"AppData"), nullptr,
805 &type, nullptr, &size);
806 // The call to RegQueryValueExW must succeed, the type must be REG_SZ, the
807 // buffer size must not equal 0, and the buffer size be a multiple of 2.
808 if (res != ERROR_SUCCESS || type != REG_SZ || size == 0 || size % 2 != 0) {
809 ::RegCloseKey(key);
810 _retval.SetLength(0);
811 return NS_ERROR_NOT_AVAILABLE;
812 }
813
814 // |size| may or may not include room for the terminating null character
815 DWORD resultLen = size / 2;
816
817 if (!_retval.SetLength(resultLen, mozilla::fallible)) {
818 ::RegCloseKey(key);
819 _retval.SetLength(0);
820 return NS_ERROR_NOT_AVAILABLE;
821 }
822
823 auto begin = _retval.BeginWriting();
824
825 res = RegQueryValueExW(key, (aLocal ? L"Local AppData" : L"AppData"), nullptr,
826 nullptr, (LPBYTE)begin, &size);
827 ::RegCloseKey(key);
828 if (res != ERROR_SUCCESS) {
829 _retval.SetLength(0);
830 return NS_ERROR_NOT_AVAILABLE;
831 }
832
833 if (!_retval.CharAt(resultLen - 1)) {
834 // It was already null terminated.
835 _retval.Truncate(resultLen - 1);
836 }
837
838 return NS_OK;
839}
840#endif
841
842static nsresult HashInstallPath(nsAString& aInstallPath, nsAString& aPathHash) {
843 mozilla::UniquePtr<NS_tchar[]> hash;
844 bool success = ::GetInstallHash(PromiseFlatStringTPromiseFlatString<char16_t>(aInstallPath).get(), hash);
845 if (!success) {
846 return NS_ERROR_FAILURE;
847 }
848
849 // The hash string is a NS_tchar*, which is wchar* in Windows and char*
850 // elsewhere.
851#ifdef XP_WIN
852 aPathHash.Assign(hash.get());
853#else
854 aPathHash.AssignASCII(hash.get());
855#endif
856 return NS_OK;
857}
858
859/**
860 * Gets a hash of the installation directory.
861 */
862nsresult nsXREDirProvider::GetInstallHash(nsAString& aPathHash) {
863 nsAutoString stringToHash;
864
865#ifdef XP_WIN
866 if (mozilla::widget::WinUtils::HasPackageIdentity()) {
867 // For packages, the install path includes the version number, so it isn't
868 // a stable or consistent identifier for the installation. The package
869 // family name is though, so use that instead of the path.
870 stringToHash = mozilla::widget::WinUtils::GetPackageFamilyName();
871 } else
872#endif
873 {
874 nsCOMPtr<nsIFile> installDir;
875 nsCOMPtr<nsIFile> appFile;
876 bool per = false;
877 nsresult rv = GetFile(XRE_EXECUTABLE_FILE"XREExeF", &per, getter_AddRefs(appFile));
878 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 878); return rv; } } while (false)
;
879 rv = appFile->GetParent(getter_AddRefs(installDir));
880 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 880); return rv; } } while (false)
;
881
882 // It is possible that the path we have is on a case insensitive
883 // filesystem in which case the path may vary depending on how the
884 // application is called. We want to normalize the case somehow.
885#ifdef XP_WIN
886 // Windows provides a way to get the correct case.
887 if (!mozilla::widget::WinUtils::ResolveJunctionPointsAndSymLinks(
888 installDir)) {
889 NS_WARNING("Failed to resolve install directory.")NS_DebugBreak(NS_DEBUG_WARNING, "Failed to resolve install directory."
, nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp", 889
)
;
890 }
891#elif defined(MOZ_WIDGET_COCOA)
892 // On OSX roundtripping through an FSRef fixes the case.
893 FSRef ref;
894 nsCOMPtr<nsILocalFileMac> macFile = do_QueryInterface(installDir);
895 rv = macFile->GetFSRef(&ref);
896 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 896); return rv; } } while (false)
;
897 rv = NS_NewLocalFileWithFSRef(&ref, getter_AddRefs(macFile));
898 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 898); return rv; } } while (false)
;
899 installDir = static_cast<nsIFile*>(macFile);
900#endif
901 // On linux XRE_EXECUTABLE_FILE already seems to be set to the correct path.
902
903 rv = installDir->GetPath(stringToHash);
904 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 904); return rv; } } while (false)
;
905 }
906
907 // If we somehow failed to get an actual value, hashing an empty string could
908 // potentially cause some serious problems given all the things this hash is
909 // used for. So we don't allow that.
910 if (stringToHash.IsEmpty()) {
911 return NS_ERROR_FAILURE;
912 }
913
914 return HashInstallPath(stringToHash, aPathHash);
915}
916
917/**
918 * Before bug 1555319 the directory hashed can have had an incorrect case.
919 * Access to that hash is still available through this function. It is needed so
920 * we can migrate users who may have an incorrect hash in profiles.ini. This
921 * support can probably be removed in a few releases time.
922 */
923nsresult nsXREDirProvider::GetLegacyInstallHash(nsAString& aPathHash) {
924 nsCOMPtr<nsIFile> installDir;
925 nsCOMPtr<nsIFile> appFile;
926 bool per = false;
927 nsresult rv = GetFile(XRE_EXECUTABLE_FILE"XREExeF", &per, getter_AddRefs(appFile));
928 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 928); return rv; } } while (false)
;
929 rv = appFile->GetParent(getter_AddRefs(installDir));
930 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 930); return rv; } } while (false)
;
931
932 nsAutoString installPath;
933 rv = installDir->GetPath(installPath);
934 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 934); return rv; } } while (false)
;
935
936#ifdef XP_WIN
937# if defined(MOZ_THUNDERBIRD) || defined(MOZ_SUITE)
938 // Convert a 64-bit install path to what would have been the 32-bit install
939 // path to allow users to migrate their profiles from one to the other.
940 PWSTR pathX86 = nullptr;
941 HRESULT hres =
942 SHGetKnownFolderPath(FOLDERID_ProgramFilesX86, 0, nullptr, &pathX86);
943 if (SUCCEEDED(hres)) {
944 nsDependentString strPathX86(pathX86);
945 if (!StringBeginsWith(installPath, strPathX86,
946 nsCaseInsensitiveStringComparator)) {
947 PWSTR path = nullptr;
948 hres = SHGetKnownFolderPath(FOLDERID_ProgramFiles, 0, nullptr, &path);
949 if (SUCCEEDED(hres)) {
950 if (StringBeginsWith(installPath, nsDependentString(path),
951 nsCaseInsensitiveStringComparator)) {
952 installPath.Replace(0, wcslen(path), strPathX86);
953 }
954 }
955 CoTaskMemFree(path);
956 }
957 }
958 CoTaskMemFree(pathX86);
959# endif
960#endif
961 return HashInstallPath(installPath, aPathHash);
962}
963
964nsresult nsXREDirProvider::GetUpdateRootDir(nsIFile** aResult,
965 bool aGetOldLocation) {
966#ifndef XP_WIN
967 // There is no old update location on platforms other than Windows. Windows is
968 // the only platform for which we migrated the update directory.
969 if (aGetOldLocation) {
970 return NS_ERROR_NOT_IMPLEMENTED;
971 }
972#endif
973 nsCOMPtr<nsIFile> updRoot;
974 nsCOMPtr<nsIFile> appFile;
975 bool per = false;
976 nsresult rv = GetFile(XRE_EXECUTABLE_FILE"XREExeF", &per, getter_AddRefs(appFile));
977 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 977); return rv; } } while (false)
;
978 rv = appFile->GetParent(getter_AddRefs(updRoot));
979 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 979); return rv; } } while (false)
;
980
981#ifdef XP_MACOSX
982 nsCOMPtr<nsIFile> appRootDirFile;
983 nsCOMPtr<nsIFile> localDir;
984 nsAutoString appDirPath;
985 if (NS_FAILED(appFile->GetParent(getter_AddRefs(appRootDirFile)))((bool)(__builtin_expect(!!(NS_FAILED_impl(appFile->GetParent
(getter_AddRefs(appRootDirFile)))), 0)))
||
986 NS_FAILED(appRootDirFile->GetPath(appDirPath))((bool)(__builtin_expect(!!(NS_FAILED_impl(appRootDirFile->
GetPath(appDirPath))), 0)))
||
987 NS_FAILED(GetUserDataDirectoryHome(getter_AddRefs(localDir),((bool)(__builtin_expect(!!(NS_FAILED_impl(GetUserDataDirectoryHome
(getter_AddRefs(localDir), true))), 0)))
988 /* aLocal */ true))((bool)(__builtin_expect(!!(NS_FAILED_impl(GetUserDataDirectoryHome
(getter_AddRefs(localDir), true))), 0)))
) {
989 return NS_ERROR_FAILURE;
990 }
991
992 int32_t dotIndex = appDirPath.RFind(u".app");
993 if (dotIndex == kNotFound) {
994 dotIndex = appDirPath.Length();
995 }
996 appDirPath = Substring(appDirPath, 1, dotIndex - 1);
997
998 bool hasVendor = GetAppVendor() && strlen(GetAppVendor()) != 0;
999 if (hasVendor || GetAppName()) {
1000 if (NS_FAILED(localDir->AppendNative(((bool)(__builtin_expect(!!(NS_FAILED_impl(localDir->AppendNative
( nsDependentCString(hasVendor ? GetAppVendor() : GetAppName(
))))), 0)))
1001 nsDependentCString(hasVendor ? GetAppVendor() : GetAppName())))((bool)(__builtin_expect(!!(NS_FAILED_impl(localDir->AppendNative
( nsDependentCString(hasVendor ? GetAppVendor() : GetAppName(
))))), 0)))
) {
1002 return NS_ERROR_FAILURE;
1003 }
1004 } else if (NS_FAILED(localDir->AppendNative("Mozilla"_ns))((bool)(__builtin_expect(!!(NS_FAILED_impl(localDir->AppendNative
("Mozilla"_ns))), 0)))
) {
1005 return NS_ERROR_FAILURE;
1006 }
1007
1008 if (NS_FAILED(localDir->Append(u"updates"_ns))((bool)(__builtin_expect(!!(NS_FAILED_impl(localDir->Append
(u"updates"_ns))), 0)))
||
1009 NS_FAILED(localDir->AppendRelativePath(appDirPath))((bool)(__builtin_expect(!!(NS_FAILED_impl(localDir->AppendRelativePath
(appDirPath))), 0)))
) {
1010 return NS_ERROR_FAILURE;
1011 }
1012
1013 localDir.forget(aResult);
1014 return NS_OK;
1015
1016#elif XP_WIN
1017 nsAutoString installPath;
1018 rv = updRoot->GetPath(installPath);
1019 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 1019); return rv; } } while (false)
;
1020
1021 mozilla::UniquePtr<wchar_t[]> updatePath;
1022 HRESULT hrv;
1023 if (aGetOldLocation) {
1024 hrv =
1025 GetOldUpdateDirectory(PromiseFlatStringTPromiseFlatString<char16_t>(installPath).get(), updatePath);
1026 } else {
1027 hrv = GetCommonUpdateDirectory(PromiseFlatStringTPromiseFlatString<char16_t>(installPath).get(),
1028 updatePath);
1029 }
1030 if (FAILED(hrv)) {
1031 return NS_ERROR_FAILURE;
1032 }
1033 nsAutoString updatePathStr;
1034 updatePathStr.Assign(updatePath.get());
1035 MOZ_TRY(updRoot->InitWithPath(updatePathStr))__extension__({ auto mozTryVarTempResult = ::mozilla::ToResult
(updRoot->InitWithPath(updatePathStr)); if ((__builtin_expect
(!!(mozTryVarTempResult.isErr()), 0))) { return mozTryVarTempResult
.propagateErr(); } mozTryVarTempResult.unwrap(); })
;
1036 updRoot.forget(aResult);
1037 return NS_OK;
1038#else
1039 updRoot.forget(aResult);
1040 return NS_OK;
1041#endif // XP_WIN
1042}
1043
1044nsresult nsXREDirProvider::GetProfileStartupDir(nsIFile** aResult) {
1045 if (mProfileDir) {
1046 return mProfileDir->Clone(aResult);
1047 }
1048
1049 // Profile directories are only set up in the parent process.
1050 // We don't expect every caller to check if they are in the right process,
1051 // so fail immediately to avoid warning spam.
1052 NS_WARNING_ASSERTION(!XRE_IsParentProcess(),do { if (!(!XRE_IsParentProcess())) { NS_DebugBreak(NS_DEBUG_WARNING
, "tried to get profile in parent too early", "!XRE_IsParentProcess()"
, "./../../../toolkit/xre/nsXREDirProvider.cpp", 1053); } } while
(false)
1053 "tried to get profile in parent too early")do { if (!(!XRE_IsParentProcess())) { NS_DebugBreak(NS_DEBUG_WARNING
, "tried to get profile in parent too early", "!XRE_IsParentProcess()"
, "./../../../toolkit/xre/nsXREDirProvider.cpp", 1053); } } while
(false)
;
1054 return NS_ERROR_FAILURE;
1055}
1056
1057nsresult nsXREDirProvider::GetProfileDir(nsIFile** aResult) {
1058 if (!mProfileDir) {
1059 nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR"ProfD",
1060 getter_AddRefs(mProfileDir));
1061 // Guard against potential buggy directory providers that fail while also
1062 // returning something.
1063 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1064 MOZ_ASSERT(!mProfileDir,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mProfileDir)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mProfileDir))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("!mProfileDir" " ("
"Directory provider failed but returned a value" ")", "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 1065); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mProfileDir"
") (" "Directory provider failed but returned a value" ")");
do { MOZ_CrashSequence(__null, 1065); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
1065 "Directory provider failed but returned a value")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mProfileDir)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mProfileDir))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("!mProfileDir" " ("
"Directory provider failed but returned a value" ")", "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 1065); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mProfileDir"
") (" "Directory provider failed but returned a value" ")");
do { MOZ_CrashSequence(__null, 1065); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1066 mProfileDir = nullptr;
1067 }
1068 }
1069 // If we failed to get mProfileDir, this will warn for us if appropriate.
1070 return GetProfileStartupDir(aResult);
1071}
1072
1073NS_IMETHODIMPnsresult
1074nsXREDirProvider::SetUserDataDirectory(nsIFile* aFile, bool aLocal) {
1075 if (aLocal) {
1076 NS_IF_RELEASE(gDataDirHomeLocal)do { if (gDataDirHomeLocal) { (gDataDirHomeLocal)->Release
(); (gDataDirHomeLocal) = 0; } } while (0)
;
1077 NS_IF_ADDREF(gDataDirHomeLocal = aFile)ns_if_addref(gDataDirHomeLocal = aFile);
1078 } else {
1079 NS_IF_RELEASE(gDataDirHome)do { if (gDataDirHome) { (gDataDirHome)->Release(); (gDataDirHome
) = 0; } } while (0)
;
1080 NS_IF_ADDREF(gDataDirHome = aFile)ns_if_addref(gDataDirHome = aFile);
1081 }
1082
1083 return NS_OK;
1084}
1085
1086/* static */
1087nsresult nsXREDirProvider::SetUserDataProfileDirectory(nsCOMPtr<nsIFile>& aFile,
1088 bool aLocal) {
1089 if (aLocal) {
1090 gDataDirProfileLocal = aFile;
1091 } else {
1092 gDataDirProfile = aFile;
1093 }
1094
1095 return NS_OK;
1096}
1097
1098/* static */
1099nsresult nsXREDirProvider::ClearUserDataProfileDirectoryFromGTest(
1100 nsIFile** aLocal, nsIFile** aGlobal) {
1101 if (gDataDirProfileLocal) {
1102 gDataDirProfileLocal->Clone(aLocal);
1103 gDataDirProfileLocal = nullptr;
1104 }
1105
1106 if (gDataDirProfile) {
1107 gDataDirProfile->Clone(aGlobal);
1108 gDataDirProfile = nullptr;
1109 }
1110
1111 return NS_OK;
1112}
1113
1114/* static */
1115nsresult nsXREDirProvider::RestoreUserDataProfileDirectoryFromGTest(
1116 nsCOMPtr<nsIFile>& aLocal, nsCOMPtr<nsIFile>& aGlobal) {
1117 gDataDirProfileLocal = aLocal;
1118 gDataDirProfile = aGlobal;
1119
1120 return NS_OK;
1121}
1122
1123// Return the home directory that will contain user data
1124nsresult nsXREDirProvider::GetUserDataDirectoryHome(nsIFile** aFile,
1125 bool aLocal,
1126 bool aForceLegacy) {
1127 // Copied from nsAppFileLocationProvider (more or less)
1128 nsCOMPtr<nsIFile> localDir;
1129
1130 if (aLocal && gDataDirHomeLocal) {
1131 return gDataDirHomeLocal->Clone(aFile);
1132 }
1133 if (!aLocal && gDataDirHome) {
1134 return gDataDirHome->Clone(aFile);
1135 }
1136
1137#if defined(XP_MACOSX)
1138 FSRef fsRef;
1139 OSType folderType;
1140 if (aLocal) {
1141 folderType = kCachedDataFolderType;
1142 } else {
1143# ifdef MOZ_THUNDERBIRD
1144 folderType = kDomainLibraryFolderType;
1145# else
1146 folderType = kApplicationSupportFolderType;
1147# endif
1148 }
1149 OSErr err = ::FSFindFolder(kUserDomain, folderType, kCreateFolder, &fsRef);
1150 NS_ENSURE_FALSE(err, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(!(err))), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "!(err)" ") failed", nullptr
, "./../../../toolkit/xre/nsXREDirProvider.cpp", 1150); return
NS_ERROR_FAILURE; } } while (false)
;
1151
1152 nsCOMPtr<nsILocalFileMac> dirFileMac;
1153 MOZ_TRY(NS_NewLocalFileWithFSRef(&fsRef, getter_AddRefs(dirFileMac)))__extension__({ auto mozTryVarTempResult = ::mozilla::ToResult
(NS_NewLocalFileWithFSRef(&fsRef, getter_AddRefs(dirFileMac
))); if ((__builtin_expect(!!(mozTryVarTempResult.isErr()), 0
))) { return mozTryVarTempResult.propagateErr(); } mozTryVarTempResult
.unwrap(); })
;
1154 localDir = dirFileMac.forget();
1155#elif defined(XP_IOS)
1156 nsAutoCString userDir;
1157 nsresult rv;
1158 if (GetUIKitDirectory(aLocal, userDir)) {
1159 rv = NS_NewNativeLocalFile(userDir, getter_AddRefs(localDir));
1160 } else {
1161 rv = NS_ERROR_FAILURE;
1162 }
1163 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 1163); return rv; } } while (false)
;
1164#elif defined(XP_WIN)
1165 nsresult rv;
1166 nsString path;
1167 if (aLocal) {
1168 rv = GetShellFolderPath(FOLDERID_LocalAppData, path);
1169 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) rv = GetRegWindowsAppDataFolder(aLocal, path);
1170 }
1171 if (!aLocal || NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1172 rv = GetShellFolderPath(FOLDERID_RoamingAppData, path);
1173 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1174 if (!aLocal) rv = GetRegWindowsAppDataFolder(aLocal, path);
1175 }
1176 }
1177 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 1177); return rv; } } while (false)
;
1178
1179 MOZ_TRY(NS_NewLocalFile(path, getter_AddRefs(localDir)))__extension__({ auto mozTryVarTempResult = ::mozilla::ToResult
(NS_NewLocalFile(path, getter_AddRefs(localDir))); if ((__builtin_expect
(!!(mozTryVarTempResult.isErr()), 0))) { return mozTryVarTempResult
.propagateErr(); } mozTryVarTempResult.unwrap(); })
;
1180#elif defined(XP_UNIX1)
1181 const char* homeDir = PR_GetEnv("HOME");
1182 if (!homeDir || !*homeDir) return NS_ERROR_FAILURE;
1183
1184# ifdef ANDROID /* We want (ProfD == ProfLD) on Android. */
1185 MOZ_TRY(NS_NewNativeLocalFile(nsDependentCString(homeDir),__extension__({ auto mozTryVarTempResult = ::mozilla::ToResult
(NS_NewNativeLocalFile(nsDependentCString(homeDir), getter_AddRefs
(localDir))); if ((__builtin_expect(!!(mozTryVarTempResult.isErr
()), 0))) { return mozTryVarTempResult.propagateErr(); } mozTryVarTempResult
.unwrap(); })
1186 getter_AddRefs(localDir)))__extension__({ auto mozTryVarTempResult = ::mozilla::ToResult
(NS_NewNativeLocalFile(nsDependentCString(homeDir), getter_AddRefs
(localDir))); if ((__builtin_expect(!!(mozTryVarTempResult.isErr
()), 0))) { return mozTryVarTempResult.propagateErr(); } mozTryVarTempResult
.unwrap(); })
;
1187# else
1188 if (aLocal) {
1189 // Not forcing legacy because cache can be lost without consequences, so
1190 // there is no real requirement to keep compatibility here
1191 MOZ_TRY(nsXREDirProvider::GetLegacyOrXDGCachePath(__extension__({ auto mozTryVarTempResult = ::mozilla::ToResult
(nsXREDirProvider::GetLegacyOrXDGCachePath( homeDir, getter_AddRefs
(localDir))); if ((__builtin_expect(!!(mozTryVarTempResult.isErr
()), 0))) { return mozTryVarTempResult.propagateErr(); } mozTryVarTempResult
.unwrap(); })
1192 homeDir, getter_AddRefs(localDir)))__extension__({ auto mozTryVarTempResult = ::mozilla::ToResult
(nsXREDirProvider::GetLegacyOrXDGCachePath( homeDir, getter_AddRefs
(localDir))); if ((__builtin_expect(!!(mozTryVarTempResult.isErr
()), 0))) { return mozTryVarTempResult.propagateErr(); } mozTryVarTempResult
.unwrap(); })
;
1193 } else {
1194 MOZ_TRY(nsXREDirProvider::GetLegacyOrXDGHomePath(__extension__({ auto mozTryVarTempResult = ::mozilla::ToResult
(nsXREDirProvider::GetLegacyOrXDGHomePath( homeDir, getter_AddRefs
(localDir), aForceLegacy)); if ((__builtin_expect(!!(mozTryVarTempResult
.isErr()), 0))) { return mozTryVarTempResult.propagateErr(); }
mozTryVarTempResult.unwrap(); })
1195 homeDir, getter_AddRefs(localDir), aForceLegacy))__extension__({ auto mozTryVarTempResult = ::mozilla::ToResult
(nsXREDirProvider::GetLegacyOrXDGHomePath( homeDir, getter_AddRefs
(localDir), aForceLegacy)); if ((__builtin_expect(!!(mozTryVarTempResult
.isErr()), 0))) { return mozTryVarTempResult.propagateErr(); }
mozTryVarTempResult.unwrap(); })
;
1196 }
1197# endif // ANDROID
1198#else
1199# error "Don't know how to get product dir on your platform"
1200#endif
1201
1202 localDir.forget(aFile);
1203 return NS_OK;
1204}
1205
1206nsresult nsXREDirProvider::GetSysUserExtensionsDirectory(nsIFile** aFile) {
1207 nsCOMPtr<nsIFile> localDir;
1208 nsresult rv = GetUserDataDirectoryHome(
1209 getter_AddRefs(localDir), /* aLocal */ false, /* aForceLegacy */ true);
1210 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 1210); return rv; } } while (false)
;
1211
1212 rv = AppendSysUserExtensionPath(localDir);
1213 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 1213); return rv; } } while (false)
;
1214
1215 // We used to unconditionally create the directory here, but that results in
1216 // an unwanted ~/.mozilla/extensions/ in violation of the XDG basedir spec,
1217 // which expresses a preference for ~/.config/mozilla/.
1218 //
1219 // Since we no longer support sideloading from this directory, unless
1220 // MOZ_ALLOW_ADDON_SIDELOAD is set, the creation of the directory is almost
1221 // always redundant, so skip the creation of the directory.
1222
1223 localDir.forget(aFile);
1224 return NS_OK;
1225}
1226
1227#if defined(XP_UNIX1) || defined(XP_MACOSX)
1228nsresult nsXREDirProvider::GetSystemExtensionsDirectory(nsIFile** aFile) {
1229 nsresult rv;
1230 nsCOMPtr<nsIFile> localDir;
1231
1232 rv = GetSystemParentDirectory(getter_AddRefs(localDir));
1233 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
1234 constexpr auto sExtensions =
1235# if defined(XP_MACOSX)
1236 "Extensions"_ns
1237# else
1238 "extensions"_ns
1239# endif
1240 ;
1241
1242 rv = localDir->AppendNative(sExtensions);
1243 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
1244 localDir.forget(aFile);
1245 }
1246 }
1247 return rv;
1248}
1249#endif
1250
1251nsresult nsXREDirProvider::GetUserDataDirectory(nsIFile** aFile, bool aLocal) {
1252 nsCOMPtr<nsIFile> localDir;
1253 nsCOMPtr<nsIFile> customDir = mozilla::GetFileFromEnv("MOZ_APP_DATA");
1254 nsCOMPtr<nsIFile> customLocalDir =
1255 mozilla::GetFileFromEnv("MOZ_LOCAL_APP_DATA");
1256
1257 if (aLocal && gDataDirProfileLocal) {
1258 return gDataDirProfileLocal->Clone(aFile);
1259 }
1260 if (!aLocal && gDataDirProfile) {
1261 return gDataDirProfile->Clone(aFile);
1262 }
1263
1264 nsresult rv;
1265 if (aLocal && customLocalDir) {
1266 localDir = customLocalDir;
1267 } else if (!aLocal && customDir) {
1268 localDir = customDir;
1269 } else {
1270 rv = GetUserDataDirectoryHome(getter_AddRefs(localDir), aLocal);
1271 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 1271); return rv; } } while (false)
;
1272
1273 rv = AppendProfilePath(localDir, aLocal);
1274 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 1274); return rv; } } while (false)
;
1275 }
1276
1277 rv = EnsureDirectoryExists(localDir);
1278 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 1278); return rv; } } while (false)
;
1279
1280 nsXREDirProvider::SetUserDataProfileDirectory(localDir, aLocal);
1281
1282 return localDir->Clone(aFile);
1283}
1284
1285nsresult nsXREDirProvider::EnsureDirectoryExists(nsIFile* aDirectory) {
1286 nsresult rv = aDirectory->Create(nsIFile::DIRECTORY_TYPE, 0700);
1287
1288 if (rv == NS_ERROR_FILE_ALREADY_EXISTS) {
1289 rv = NS_OK;
1290 }
1291 return rv;
1292}
1293
1294nsresult nsXREDirProvider::AppendSysUserExtensionPath(nsIFile* aFile) {
1295 NS_ASSERTION(aFile, "Null pointer!")do { if (!(aFile)) { NS_DebugBreak(NS_DEBUG_ASSERTION, "Null pointer!"
, "aFile", "./../../../toolkit/xre/nsXREDirProvider.cpp", 1295
); MOZ_PretendNoReturn(); } } while (0)
;
1296
1297 nsresult rv;
1298
1299#if defined(XP_MACOSX) || defined(XP_WIN)
1300
1301 static const char* const sXR = "Mozilla";
1302 rv = aFile->AppendNative(nsDependentCString(sXR));
1303 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 1303); return rv; } } while (false)
;
1304
1305 static const char* const sExtensions = "Extensions";
1306 rv = aFile->AppendNative(nsDependentCString(sExtensions));
1307 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 1307); return rv; } } while (false)
;
1308
1309#elif defined(XP_UNIX1)
1310
1311 static const char* const sXR = ".mozilla";
1312 rv = aFile->AppendNative(nsDependentCString(sXR));
1313 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 1313); return rv; } } while (false)
;
1314
1315 static const char* const sExtensions = "extensions";
1316 rv = aFile->AppendNative(nsDependentCString(sExtensions));
1317 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 1317); return rv; } } while (false)
;
1318
1319#else
1320# error "Don't know how to get XRE user extension path on your platform"
1321#endif
1322 return NS_OK;
1323}
1324
1325#if defined(MOZ_WIDGET_GTK1)
1326/*
1327 * Return whether MOZ_LEGACY_HOME == 1, via environment or at build time
1328 */
1329bool nsXREDirProvider::IsForceLegacyHome() {
1330# if !defined(MOZ_LEGACY_HOME)
1331 const char* legacyhomedir = PR_GetEnv("MOZ_LEGACY_HOME");
1332 return legacyhomedir && legacyhomedir[0] == '1';
1333# else
1334 return true;
1335# endif
1336}
1337
1338/* static */
1339nsresult nsXREDirProvider::AppendFromAppData(nsIFile* aFile, bool aIsDotted) {
1340 // This might happen in xpcshell so assert that it is indeed in a xpcshell
1341 // test. This assumes the xpcshell are ran through test harness.
1342 if (!gAppData) {
1343 mozilla::DebugOnly<const char*> xpcshell =
1344 PR_GetEnv("XPCSHELL_TEST_PROFILE_DIR");
1345 MOZ_ASSERT(xpcshell, "gAppData can only be nullptr in xpcshell tests")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(xpcshell)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(xpcshell))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("xpcshell" " (" "gAppData can only be nullptr in xpcshell tests"
")", "./../../../toolkit/xre/nsXREDirProvider.cpp", 1345); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "xpcshell" ") (" "gAppData can only be nullptr in xpcshell tests"
")"); do { MOZ_CrashSequence(__null, 1345); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1346 return NS_OK;
1347 }
1348
1349 // Similar to nsXREDirProvider::AppendProfilePath.
1350 // TODO: Bug 1990407 - Evaluate if refactoring might be required there in the
1351 // future?
1352 if (gAppData->profile) {
1353 nsAutoCString profile;
1354# if defined(MOZ_THUNDERBIRD)
1355 if (gAppData->profile[0] != '.') {
1356 profile.Assign('.');
1357 }
1358# endif
1359 profile.Append(gAppData->profile);
1360 MOZ_TRY(aFile->AppendRelativeNativePath(profile))__extension__({ auto mozTryVarTempResult = ::mozilla::ToResult
(aFile->AppendRelativeNativePath(profile)); if ((__builtin_expect
(!!(mozTryVarTempResult.isErr()), 0))) { return mozTryVarTempResult
.propagateErr(); } mozTryVarTempResult.unwrap(); })
;
1361 } else {
1362 nsAutoCString vendor;
1363 nsAutoCString appName;
1364 vendor = gAppData->vendor;
1365 appName = gAppData->name;
1366 ToLowerCase(vendor);
1367 ToLowerCase(appName);
1368
1369 MOZ_TRY(aFile->AppendRelativeNativePath(aIsDotted ? ("."_ns + vendor)__extension__({ auto mozTryVarTempResult = ::mozilla::ToResult
(aFile->AppendRelativeNativePath(aIsDotted ? ("."_ns + vendor
) : vendor)); if ((__builtin_expect(!!(mozTryVarTempResult.isErr
()), 0))) { return mozTryVarTempResult.propagateErr(); } mozTryVarTempResult
.unwrap(); })
1370 : vendor))__extension__({ auto mozTryVarTempResult = ::mozilla::ToResult
(aFile->AppendRelativeNativePath(aIsDotted ? ("."_ns + vendor
) : vendor)); if ((__builtin_expect(!!(mozTryVarTempResult.isErr
()), 0))) { return mozTryVarTempResult.propagateErr(); } mozTryVarTempResult
.unwrap(); })
;
1371 MOZ_TRY(aFile->AppendRelativeNativePath(appName))__extension__({ auto mozTryVarTempResult = ::mozilla::ToResult
(aFile->AppendRelativeNativePath(appName)); if ((__builtin_expect
(!!(mozTryVarTempResult.isErr()), 0))) { return mozTryVarTempResult
.propagateErr(); } mozTryVarTempResult.unwrap(); })
;
1372 }
1373
1374 return NS_OK;
1375}
1376
1377/*
1378 * Check if legacy directory exists, which can be:
1379 * (1) $HOME/.<gAppData->vendor>/<gAppData->appName>
1380 * (2) $HOME/<gAppData->profile> on Firefox or
1381 * $HOME/.<gAppData->profile> on Thunderbird
1382 * (3) $HOME/<MOZ_USER_DIR>
1383 *
1384 * The MOZ_USER_DIR will also be defined in case (1), so first check the deeper
1385 * directory.
1386 */
1387bool nsXREDirProvider::LegacyHomeExists(nsIFile** aFile) {
1388 bool exists;
1389 nsDependentCString homeDir(PR_GetEnv("HOME"));
1390 nsCOMPtr<nsIFile> localDir;
1391 nsCOMPtr<nsIFile> parentDir;
1392
1393 // check old config ~/.mozilla
1394 nsresult rv = NS_NewNativeLocalFile(homeDir, getter_AddRefs(localDir));
1395 NS_ENSURE_SUCCESS(rv, false)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "false", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 1395); return false; } } while (false)
;
1396
1397 rv = localDir->Clone(getter_AddRefs(parentDir));
1398 NS_ENSURE_SUCCESS(rv, false)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "false", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 1398); return false; } } while (false)
;
1399
1400 // Handle (1) and (2)
1401 rv = AppendFromAppData(localDir, true);
1402 NS_ENSURE_SUCCESS(rv, false)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "false", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 1402); return false; } } while (false)
;
1403
1404 rv = localDir->Exists(&exists);
1405 NS_ENSURE_SUCCESS(rv, false)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "false", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 1405); return false; } } while (false)
;
1406
1407 // Give a chance to (3)
1408 if (!exists) {
1409 nsCOMPtr<nsIFile> userDir;
1410 rv = parentDir->Clone(getter_AddRefs(userDir));
1411 NS_ENSURE_SUCCESS(rv, false)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "false", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 1411); return false; } } while (false)
;
1412
1413 nsAutoCString mozUserDir;
1414 mozUserDir = nsLiteralCString(MOZ_USER_DIR"mozilla");
1415
1416 rv = userDir->AppendRelativeNativePath(mozUserDir);
1417 NS_ENSURE_SUCCESS(rv, false)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "false", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 1417); return false; } } while (false)
;
1418
1419 rv = userDir->Exists(&exists);
1420 NS_ENSURE_SUCCESS(rv, false)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "false", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 1420); return false; } } while (false)
;
1421 }
1422
1423 // If required, return the parent dir that may exist.
1424 if (aFile) {
1425 parentDir.forget(aFile);
1426 }
1427
1428 return exists;
1429}
1430
1431void MaybeRecordXdgTelemetry(
1432 nsXREDirProvider::legacyOrXDGHomeTelemetry aValue) {
1433 if (gXdgTelemetry == nsXREDirProvider::legacyOrXDGHomeTelemetry::empty) {
1434 gXdgTelemetry = aValue;
1435 }
1436}
1437
1438/* static */
1439nsresult nsXREDirProvider::GetLegacyOrXDGEnvValue(const char* aHomeDir,
1440 const char* aEnvName,
1441 nsCString aSubdir,
1442 nsIFile** aFile,
1443 bool* aWasFromEnv) {
1444 nsCOMPtr<nsIFile> localDir;
1445 nsresult rv = NS_OK;
1446
1447 const char* envValue = PR_GetEnv(aEnvName);
1448 if (envValue && *envValue) {
1449 rv = NS_NewNativeLocalFile(nsDependentCString(envValue),
1450 getter_AddRefs(localDir));
1451 if (aWasFromEnv) {
1452 *aWasFromEnv = true;
1453 }
1454 }
1455
1456 // Explicitly check for rv failure because in case we get passed an env
1457 // value that is an invalid dir by the XDG specification level, it should
1458 // be ignored. Per
1459 // https://specifications.freedesktop.org/basedir-spec/0.8/:
1460 // "If an implementation encounters a relative path in any of
1461 // these variables it should consider the path invalid and ignore it."
1462 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || !envValue || !*envValue) {
1463 MOZ_TRY(NS_NewNativeLocalFile(nsDependentCString(aHomeDir),__extension__({ auto mozTryVarTempResult = ::mozilla::ToResult
(NS_NewNativeLocalFile(nsDependentCString(aHomeDir), getter_AddRefs
(localDir))); if ((__builtin_expect(!!(mozTryVarTempResult.isErr
()), 0))) { return mozTryVarTempResult.propagateErr(); } mozTryVarTempResult
.unwrap(); })
1464 getter_AddRefs(localDir)))__extension__({ auto mozTryVarTempResult = ::mozilla::ToResult
(NS_NewNativeLocalFile(nsDependentCString(aHomeDir), getter_AddRefs
(localDir))); if ((__builtin_expect(!!(mozTryVarTempResult.isErr
()), 0))) { return mozTryVarTempResult.propagateErr(); } mozTryVarTempResult
.unwrap(); })
;
1465 MOZ_TRY(localDir->AppendNative(aSubdir))__extension__({ auto mozTryVarTempResult = ::mozilla::ToResult
(localDir->AppendNative(aSubdir)); if ((__builtin_expect(!
!(mozTryVarTempResult.isErr()), 0))) { return mozTryVarTempResult
.propagateErr(); } mozTryVarTempResult.unwrap(); })
;
1466 if (aWasFromEnv) {
1467 *aWasFromEnv = false;
1468 }
1469 }
1470
1471 localDir.forget(aFile);
1472 return NS_OK;
1473}
1474
1475/* static */
1476nsresult nsXREDirProvider::GetLegacyOrXDGCachePath(const char* aHomeDir,
1477 nsIFile** aFile) {
1478 return GetLegacyOrXDGEnvValue(aHomeDir, "XDG_CACHE_HOME", ".cache"_ns, aFile,
1479 nullptr);
1480}
1481
1482/*
1483 * Check if XDG_CONFIG_HOME is here and use it or default to ${aHomeDir}/.config
1484 */
1485/* static */
1486nsresult nsXREDirProvider::GetLegacyOrXDGConfigHome(const char* aHomeDir,
1487 nsIFile** aFile) {
1488 bool wasFromEnv = false;
1489 nsresult rv = GetLegacyOrXDGEnvValue(aHomeDir, "XDG_CONFIG_HOME",
1490 ".config"_ns, aFile, &wasFromEnv);
1491 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && wasFromEnv) {
1492 MaybeRecordXdgTelemetry(legacyOrXDGHomeTelemetry::xdgConfigHome);
1493 } else {
1494 MaybeRecordXdgTelemetry(legacyOrXDGHomeTelemetry::xdgDefault);
1495 }
1496 return rv;
1497}
1498
1499// Attempt to construct the HOME path depending on XDG or legacy status.
1500nsresult nsXREDirProvider::GetLegacyOrXDGHomePath(const char* aHomeDir,
1501 nsIFile** aFile,
1502 bool aForceLegacy) {
1503 nsCOMPtr<nsIFile> parentDir;
1504 nsDependentCString homeDir(aHomeDir);
1505
1506 bool exists = LegacyHomeExists(getter_AddRefs(parentDir));
1507 if (exists || IsForceLegacyHome() || aForceLegacy) {
1508 if (exists) {
1509 MaybeRecordXdgTelemetry(legacyOrXDGHomeTelemetry::legacyExists);
1510 } else {
1511 MaybeRecordXdgTelemetry(legacyOrXDGHomeTelemetry::legacyForced);
1512 }
1513 parentDir.forget(aFile);
1514 return NS_OK;
1515 }
1516
1517 nsCOMPtr<nsIFile> localDir;
1518
1519 // If the build was made with --with-user-appdir=.fooProfile it needs to be
1520 // applied and considered as a legacy path.
1521 nsAutoCString mozUserDir;
1522 mozUserDir = nsLiteralCString(MOZ_USER_DIR"mozilla");
1523 if (mozUserDir.get()[0] == '.') {
1524 MOZ_TRY(NS_NewNativeLocalFile(nsDependentCString(aHomeDir),__extension__({ auto mozTryVarTempResult = ::mozilla::ToResult
(NS_NewNativeLocalFile(nsDependentCString(aHomeDir), getter_AddRefs
(localDir))); if ((__builtin_expect(!!(mozTryVarTempResult.isErr
()), 0))) { return mozTryVarTempResult.propagateErr(); } mozTryVarTempResult
.unwrap(); })
1525 getter_AddRefs(localDir)))__extension__({ auto mozTryVarTempResult = ::mozilla::ToResult
(NS_NewNativeLocalFile(nsDependentCString(aHomeDir), getter_AddRefs
(localDir))); if ((__builtin_expect(!!(mozTryVarTempResult.isErr
()), 0))) { return mozTryVarTempResult.propagateErr(); } mozTryVarTempResult
.unwrap(); })
;
1526 MOZ_TRY(localDir->AppendRelativeNativePath(mozUserDir))__extension__({ auto mozTryVarTempResult = ::mozilla::ToResult
(localDir->AppendRelativeNativePath(mozUserDir)); if ((__builtin_expect
(!!(mozTryVarTempResult.isErr()), 0))) { return mozTryVarTempResult
.propagateErr(); } mozTryVarTempResult.unwrap(); })
;
1527 } else {
1528 // This might happen in xpcshell so assert that it is indeed in a xpcshell
1529 // test
1530 if (!gAppData) {
1531 mozilla::DebugOnly<const char*> xpcshell =
1532 PR_GetEnv("XPCSHELL_TEST_PROFILE_DIR");
1533 MOZ_ASSERT(xpcshell, "gAppData can only be nullptr in xpcshell tests")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(xpcshell)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(xpcshell))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("xpcshell" " (" "gAppData can only be nullptr in xpcshell tests"
")", "./../../../toolkit/xre/nsXREDirProvider.cpp", 1533); AnnotateMozCrashReason
("MOZ_ASSERT" "(" "xpcshell" ") (" "gAppData can only be nullptr in xpcshell tests"
")"); do { MOZ_CrashSequence(__null, 1533); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1534 return NS_OK;
1535 }
1536
1537 // If the build was made against a specific profile name, MOZ_APP_PROFILE=
1538 // then make sure we respect this and dont move to XDG directory
1539 //
1540 // Only do this on Firefox.
1541 //
1542 // For Thunderbird, it always defines MOZ_APP_PROFILE=thunderbird. Hence,
1543 // check if the gAppData->profile value is set to something else, indicating
1544 // of a specific build where legacy needs to be forced, similar to the
1545 // Firefox handling. Both casing are verified to account for systems where
1546 // that matters.
1547 if (gAppData->profile
1548# if defined(MOZ_THUNDERBIRD)
1549 && strcmp(gAppData->profile, "thunderbird") != 0 &&
1550 strcmp(gAppData->profile, "Thunderbird") != 0
1551# endif
1552 ) {
1553 MOZ_TRY(NS_NewNativeLocalFile(nsDependentCString(aHomeDir),__extension__({ auto mozTryVarTempResult = ::mozilla::ToResult
(NS_NewNativeLocalFile(nsDependentCString(aHomeDir), getter_AddRefs
(localDir))); if ((__builtin_expect(!!(mozTryVarTempResult.isErr
()), 0))) { return mozTryVarTempResult.propagateErr(); } mozTryVarTempResult
.unwrap(); })
1554 getter_AddRefs(localDir)))__extension__({ auto mozTryVarTempResult = ::mozilla::ToResult
(NS_NewNativeLocalFile(nsDependentCString(aHomeDir), getter_AddRefs
(localDir))); if ((__builtin_expect(!!(mozTryVarTempResult.isErr
()), 0))) { return mozTryVarTempResult.propagateErr(); } mozTryVarTempResult
.unwrap(); })
;
1555 } else {
1556 MOZ_TRY(GetLegacyOrXDGConfigHome(aHomeDir, getter_AddRefs(localDir)))__extension__({ auto mozTryVarTempResult = ::mozilla::ToResult
(GetLegacyOrXDGConfigHome(aHomeDir, getter_AddRefs(localDir))
); if ((__builtin_expect(!!(mozTryVarTempResult.isErr()), 0))
) { return mozTryVarTempResult.propagateErr(); } mozTryVarTempResult
.unwrap(); })
;
1557 MOZ_TRY(localDir->Clone(getter_AddRefs(parentDir)))__extension__({ auto mozTryVarTempResult = ::mozilla::ToResult
(localDir->Clone(getter_AddRefs(parentDir))); if ((__builtin_expect
(!!(mozTryVarTempResult.isErr()), 0))) { return mozTryVarTempResult
.propagateErr(); } mozTryVarTempResult.unwrap(); })
;
1558 }
1559
1560 MOZ_TRY(AppendFromAppData(localDir, false))__extension__({ auto mozTryVarTempResult = ::mozilla::ToResult
(AppendFromAppData(localDir, false)); if ((__builtin_expect(!
!(mozTryVarTempResult.isErr()), 0))) { return mozTryVarTempResult
.propagateErr(); } mozTryVarTempResult.unwrap(); })
;
1561 }
1562
1563 // If required return the parent directory that matches the profile root
1564 // directory.
1565 if (aFile) {
1566 parentDir.forget(aFile);
1567 }
1568
1569 // The profile root directory needs to exists at that point.
1570 MOZ_TRY(EnsureDirectoryExists(localDir))__extension__({ auto mozTryVarTempResult = ::mozilla::ToResult
(EnsureDirectoryExists(localDir)); if ((__builtin_expect(!!(mozTryVarTempResult
.isErr()), 0))) { return mozTryVarTempResult.propagateErr(); }
mozTryVarTempResult.unwrap(); })
;
1571
1572 return NS_OK;
1573}
1574#endif // defined(MOZ_WIDGET_GTK)
1575
1576nsresult nsXREDirProvider::AppendProfilePath(nsIFile* aFile, bool aLocal) {
1577 NS_ASSERTION(aFile, "Null pointer!")do { if (!(aFile)) { NS_DebugBreak(NS_DEBUG_ASSERTION, "Null pointer!"
, "aFile", "./../../../toolkit/xre/nsXREDirProvider.cpp", 1577
); MOZ_PretendNoReturn(); } } while (0)
;
1578
1579 // If there is no XREAppData then there is no information to use to build
1580 // the profile path so just do nothing. This should only happen in xpcshell
1581 // tests.
1582 if (!gAppData) {
1583 return NS_OK;
1584 }
1585
1586 // Similar to nsXREDirProvider::AppendFromAppData.
1587 // TODO: evaluate if refactoring might be required there in the future?
1588
1589 nsAutoCString profile;
1590 nsAutoCString appName;
1591 nsAutoCString vendor;
1592 if (gAppData->profile) {
1593 profile = gAppData->profile;
1594 } else {
1595 appName = gAppData->name;
1596 vendor = gAppData->vendor;
1597 }
1598
1599 nsresult rv = NS_OK;
1600
1601#if defined(XP_MACOSX)
1602 if (!profile.IsEmpty()) {
1603 rv = AppendProfileString(aFile, profile.get());
1604 } else {
1605 // Note that MacOS ignores the vendor when creating the profile hierarchy -
1606 // all application preferences directories live alongside one another in
1607 // ~/Library/Application Support/
1608 rv = aFile->AppendNative(appName);
1609 }
1610 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 1610); return rv; } } while (false)
;
1611
1612#elif defined(XP_WIN)
1613 if (!profile.IsEmpty()) {
1614 rv = AppendProfileString(aFile, profile.get());
1615 } else {
1616 if (!vendor.IsEmpty()) {
1617 rv = aFile->AppendNative(vendor);
1618 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 1618); return rv; } } while (false)
;
1619 }
1620 rv = aFile->AppendNative(appName);
1621 }
1622 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 1622); return rv; } } while (false)
;
1623
1624#elif defined(ANDROID)
1625 // The directory used for storing profiles
1626 // The parent of this directory is set in GetUserDataDirectoryHome
1627 // XXX: handle gAppData->profile properly
1628 // XXXsmaug ...and the rest of the profile creation!
1629 rv = aFile->AppendNative(nsDependentCString("mozilla"));
1630 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 1630); return rv; } } while (false)
;
1631#elif defined(XP_UNIX1)
1632 nsAutoCString folder;
1633 // Make it hidden (by starting with "."), except when local (the
1634 // profile is already under ~/.cache or XDG_CACHE_HOME).
1635 if (!aLocal
1636# if defined(MOZ_WIDGET_GTK1)
1637 && (IsForceLegacyHome() || LegacyHomeExists(nullptr))
1638# endif
1639 ) {
1640 folder.Assign('.');
1641 }
1642
1643 if (!profile.IsEmpty()) {
1644 // Skip any leading path characters
1645 const char* profileStart = profile.get();
1646 while (*profileStart == '/' || *profileStart == '\\') profileStart++;
1647
1648 // On the off chance that someone wanted their folder to be hidden don't
1649 // let it become ".."
1650 if (*profileStart == '.' && !aLocal) profileStart++;
1651
1652 folder.Append(profileStart);
1653 ToLowerCase(folder);
1654
1655 rv = AppendProfileString(aFile, folder.get());
1656 } else {
1657 if (!vendor.IsEmpty()) {
1658 folder.Append(vendor);
1659 ToLowerCase(folder);
1660
1661 rv = aFile->AppendNative(folder);
1662 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 1662); return rv; } } while (false)
;
1663
1664 folder.Truncate();
1665 }
1666
1667 // This can be the case in tests.
1668 if (!appName.IsEmpty()) {
1669 folder.Append(appName);
1670 ToLowerCase(folder);
1671
1672 rv = aFile->AppendNative(folder);
1673 }
1674 }
1675 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 1675); return rv; } } while (false)
;
1676
1677#else
1678# error "Don't know how to get profile path on your platform"
1679#endif
1680 return NS_OK;
1681}
1682
1683nsresult nsXREDirProvider::AppendProfileString(nsIFile* aFile,
1684 const char* aPath) {
1685 NS_ASSERTION(aFile, "Null file!")do { if (!(aFile)) { NS_DebugBreak(NS_DEBUG_ASSERTION, "Null file!"
, "aFile", "./../../../toolkit/xre/nsXREDirProvider.cpp", 1685
); MOZ_PretendNoReturn(); } } while (0)
;
1686 NS_ASSERTION(aPath, "Null path!")do { if (!(aPath)) { NS_DebugBreak(NS_DEBUG_ASSERTION, "Null path!"
, "aPath", "./../../../toolkit/xre/nsXREDirProvider.cpp", 1686
); MOZ_PretendNoReturn(); } } while (0)
;
1687
1688 nsAutoCString pathDup(aPath);
1689
1690 char* path = pathDup.BeginWriting();
1691
1692 nsresult rv;
1693 char* subdir;
1694 while ((subdir = NS_strtok("/\\", &path))) {
1695 rv = aFile->AppendNative(nsDependentCString(subdir));
1696 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../toolkit/xre/nsXREDirProvider.cpp"
, 1696); return rv; } } while (false)
;
1697 }
1698
1699 return NS_OK;
1700}