xpcom/io/nsAppFileLocationProvider.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #include "nsAppFileLocationProvider.h"
michael@0 7 #include "nsAppDirectoryServiceDefs.h"
michael@0 8 #include "nsDirectoryServiceDefs.h"
michael@0 9 #include "nsIAtom.h"
michael@0 10 #include "nsIFile.h"
michael@0 11 #include "nsString.h"
michael@0 12 #include "nsXPIDLString.h"
michael@0 13 #include "nsISimpleEnumerator.h"
michael@0 14 #include "prenv.h"
michael@0 15 #include "nsCRT.h"
michael@0 16 #include "nsXPCOMPrivate.h" // for XPCOM_FILE_PATH_SEPARATOR
michael@0 17
michael@0 18 #if defined(MOZ_WIDGET_COCOA)
michael@0 19 #include <Carbon/Carbon.h>
michael@0 20 #include "nsILocalFileMac.h"
michael@0 21 #elif defined(XP_WIN)
michael@0 22 #include <windows.h>
michael@0 23 #include <shlobj.h>
michael@0 24 #elif defined(XP_UNIX)
michael@0 25 #include <unistd.h>
michael@0 26 #include <stdlib.h>
michael@0 27 #include <sys/param.h>
michael@0 28 #endif
michael@0 29
michael@0 30
michael@0 31 // WARNING: These hard coded names need to go away. They need to
michael@0 32 // come from localizable resources
michael@0 33
michael@0 34 #if defined(MOZ_WIDGET_COCOA)
michael@0 35 #define APP_REGISTRY_NAME NS_LITERAL_CSTRING("Application Registry")
michael@0 36 #define ESSENTIAL_FILES NS_LITERAL_CSTRING("Essential Files")
michael@0 37 #elif defined(XP_WIN)
michael@0 38 #define APP_REGISTRY_NAME NS_LITERAL_CSTRING("registry.dat")
michael@0 39 #else
michael@0 40 #define APP_REGISTRY_NAME NS_LITERAL_CSTRING("appreg")
michael@0 41 #endif
michael@0 42
michael@0 43 // define default product directory
michael@0 44 #define DEFAULT_PRODUCT_DIR NS_LITERAL_CSTRING(MOZ_USER_DIR)
michael@0 45
michael@0 46 // Locally defined keys used by nsAppDirectoryEnumerator
michael@0 47 #define NS_ENV_PLUGINS_DIR "EnvPlugins" // env var MOZ_PLUGIN_PATH
michael@0 48 #define NS_USER_PLUGINS_DIR "UserPlugins"
michael@0 49
michael@0 50 #ifdef MOZ_WIDGET_COCOA
michael@0 51 #define NS_MACOSX_USER_PLUGIN_DIR "OSXUserPlugins"
michael@0 52 #define NS_MACOSX_LOCAL_PLUGIN_DIR "OSXLocalPlugins"
michael@0 53 #define NS_MACOSX_JAVA2_PLUGIN_DIR "OSXJavaPlugins"
michael@0 54 #elif XP_UNIX
michael@0 55 #define NS_SYSTEM_PLUGINS_DIR "SysPlugins"
michael@0 56 #endif
michael@0 57
michael@0 58 #define DEFAULTS_DIR_NAME NS_LITERAL_CSTRING("defaults")
michael@0 59 #define DEFAULTS_PREF_DIR_NAME NS_LITERAL_CSTRING("pref")
michael@0 60 #define DEFAULTS_PROFILE_DIR_NAME NS_LITERAL_CSTRING("profile")
michael@0 61 #define RES_DIR_NAME NS_LITERAL_CSTRING("res")
michael@0 62 #define CHROME_DIR_NAME NS_LITERAL_CSTRING("chrome")
michael@0 63 #define PLUGINS_DIR_NAME NS_LITERAL_CSTRING("plugins")
michael@0 64 #define SEARCH_DIR_NAME NS_LITERAL_CSTRING("searchplugins")
michael@0 65
michael@0 66 //*****************************************************************************
michael@0 67 // nsAppFileLocationProvider::Constructor/Destructor
michael@0 68 //*****************************************************************************
michael@0 69
michael@0 70 nsAppFileLocationProvider::nsAppFileLocationProvider()
michael@0 71 {
michael@0 72 }
michael@0 73
michael@0 74 //*****************************************************************************
michael@0 75 // nsAppFileLocationProvider::nsISupports
michael@0 76 //*****************************************************************************
michael@0 77
michael@0 78 NS_IMPL_ISUPPORTS(nsAppFileLocationProvider, nsIDirectoryServiceProvider, nsIDirectoryServiceProvider2)
michael@0 79
michael@0 80 //*****************************************************************************
michael@0 81 // nsAppFileLocationProvider::nsIDirectoryServiceProvider
michael@0 82 //*****************************************************************************
michael@0 83
michael@0 84 NS_IMETHODIMP
michael@0 85 nsAppFileLocationProvider::GetFile(const char *prop, bool *persistent, nsIFile **_retval)
michael@0 86 {
michael@0 87 if (NS_WARN_IF(!prop))
michael@0 88 return NS_ERROR_INVALID_ARG;
michael@0 89
michael@0 90 nsCOMPtr<nsIFile> localFile;
michael@0 91 nsresult rv = NS_ERROR_FAILURE;
michael@0 92
michael@0 93 *_retval = nullptr;
michael@0 94 *persistent = true;
michael@0 95
michael@0 96 #ifdef MOZ_WIDGET_COCOA
michael@0 97 FSRef fileRef;
michael@0 98 nsCOMPtr<nsILocalFileMac> macFile;
michael@0 99 #endif
michael@0 100
michael@0 101 if (nsCRT::strcmp(prop, NS_APP_APPLICATION_REGISTRY_DIR) == 0)
michael@0 102 {
michael@0 103 rv = GetProductDirectory(getter_AddRefs(localFile));
michael@0 104 }
michael@0 105 else if (nsCRT::strcmp(prop, NS_APP_APPLICATION_REGISTRY_FILE) == 0)
michael@0 106 {
michael@0 107 rv = GetProductDirectory(getter_AddRefs(localFile));
michael@0 108 if (NS_SUCCEEDED(rv))
michael@0 109 rv = localFile->AppendNative(APP_REGISTRY_NAME);
michael@0 110 }
michael@0 111 else if (nsCRT::strcmp(prop, NS_APP_DEFAULTS_50_DIR) == 0)
michael@0 112 {
michael@0 113 rv = CloneMozBinDirectory(getter_AddRefs(localFile));
michael@0 114 if (NS_SUCCEEDED(rv))
michael@0 115 rv = localFile->AppendRelativeNativePath(DEFAULTS_DIR_NAME);
michael@0 116 }
michael@0 117 else if (nsCRT::strcmp(prop, NS_APP_PREF_DEFAULTS_50_DIR) == 0)
michael@0 118 {
michael@0 119 rv = CloneMozBinDirectory(getter_AddRefs(localFile));
michael@0 120 if (NS_SUCCEEDED(rv)) {
michael@0 121 rv = localFile->AppendRelativeNativePath(DEFAULTS_DIR_NAME);
michael@0 122 if (NS_SUCCEEDED(rv))
michael@0 123 rv = localFile->AppendRelativeNativePath(DEFAULTS_PREF_DIR_NAME);
michael@0 124 }
michael@0 125 }
michael@0 126 else if (nsCRT::strcmp(prop, NS_APP_PROFILE_DEFAULTS_50_DIR) == 0 ||
michael@0 127 nsCRT::strcmp(prop, NS_APP_PROFILE_DEFAULTS_NLOC_50_DIR) == 0)
michael@0 128 {
michael@0 129 rv = CloneMozBinDirectory(getter_AddRefs(localFile));
michael@0 130 if (NS_SUCCEEDED(rv)) {
michael@0 131 rv = localFile->AppendRelativeNativePath(DEFAULTS_DIR_NAME);
michael@0 132 if (NS_SUCCEEDED(rv))
michael@0 133 rv = localFile->AppendRelativeNativePath(DEFAULTS_PROFILE_DIR_NAME);
michael@0 134 }
michael@0 135 }
michael@0 136 else if (nsCRT::strcmp(prop, NS_APP_USER_PROFILES_ROOT_DIR) == 0)
michael@0 137 {
michael@0 138 rv = GetDefaultUserProfileRoot(getter_AddRefs(localFile));
michael@0 139 }
michael@0 140 else if (nsCRT::strcmp(prop, NS_APP_USER_PROFILES_LOCAL_ROOT_DIR) == 0)
michael@0 141 {
michael@0 142 rv = GetDefaultUserProfileRoot(getter_AddRefs(localFile), true);
michael@0 143 }
michael@0 144 else if (nsCRT::strcmp(prop, NS_APP_RES_DIR) == 0)
michael@0 145 {
michael@0 146 rv = CloneMozBinDirectory(getter_AddRefs(localFile));
michael@0 147 if (NS_SUCCEEDED(rv))
michael@0 148 rv = localFile->AppendRelativeNativePath(RES_DIR_NAME);
michael@0 149 }
michael@0 150 else if (nsCRT::strcmp(prop, NS_APP_CHROME_DIR) == 0)
michael@0 151 {
michael@0 152 rv = CloneMozBinDirectory(getter_AddRefs(localFile));
michael@0 153 if (NS_SUCCEEDED(rv))
michael@0 154 rv = localFile->AppendRelativeNativePath(CHROME_DIR_NAME);
michael@0 155 }
michael@0 156 else if (nsCRT::strcmp(prop, NS_APP_PLUGINS_DIR) == 0)
michael@0 157 {
michael@0 158 rv = CloneMozBinDirectory(getter_AddRefs(localFile));
michael@0 159 if (NS_SUCCEEDED(rv))
michael@0 160 rv = localFile->AppendRelativeNativePath(PLUGINS_DIR_NAME);
michael@0 161 }
michael@0 162 #ifdef MOZ_WIDGET_COCOA
michael@0 163 else if (nsCRT::strcmp(prop, NS_MACOSX_USER_PLUGIN_DIR) == 0)
michael@0 164 {
michael@0 165 if (::FSFindFolder(kUserDomain, kInternetPlugInFolderType, false, &fileRef) == noErr) {
michael@0 166 rv = NS_NewLocalFileWithFSRef(&fileRef, true, getter_AddRefs(macFile));
michael@0 167 if (NS_SUCCEEDED(rv))
michael@0 168 localFile = macFile;
michael@0 169 }
michael@0 170 }
michael@0 171 else if (nsCRT::strcmp(prop, NS_MACOSX_LOCAL_PLUGIN_DIR) == 0)
michael@0 172 {
michael@0 173 if (::FSFindFolder(kLocalDomain, kInternetPlugInFolderType, false, &fileRef) == noErr) {
michael@0 174 rv = NS_NewLocalFileWithFSRef(&fileRef, true, getter_AddRefs(macFile));
michael@0 175 if (NS_SUCCEEDED(rv))
michael@0 176 localFile = macFile;
michael@0 177 }
michael@0 178 }
michael@0 179 else if (nsCRT::strcmp(prop, NS_MACOSX_JAVA2_PLUGIN_DIR) == 0)
michael@0 180 {
michael@0 181 static const char *const java2PluginDirPath =
michael@0 182 "/System/Library/Java/Support/Deploy.bundle/Contents/Resources/";
michael@0 183 rv = NS_NewNativeLocalFile(nsDependentCString(java2PluginDirPath), true, getter_AddRefs(localFile));
michael@0 184 }
michael@0 185 #else
michael@0 186 else if (nsCRT::strcmp(prop, NS_ENV_PLUGINS_DIR) == 0)
michael@0 187 {
michael@0 188 NS_ERROR("Don't use nsAppFileLocationProvider::GetFile(NS_ENV_PLUGINS_DIR, ...). "
michael@0 189 "Use nsAppFileLocationProvider::GetFiles(...).");
michael@0 190 const char *pathVar = PR_GetEnv("MOZ_PLUGIN_PATH");
michael@0 191 if (pathVar && *pathVar)
michael@0 192 rv = NS_NewNativeLocalFile(nsDependentCString(pathVar), true,
michael@0 193 getter_AddRefs(localFile));
michael@0 194 }
michael@0 195 else if (nsCRT::strcmp(prop, NS_USER_PLUGINS_DIR) == 0)
michael@0 196 {
michael@0 197 #ifdef ENABLE_SYSTEM_EXTENSION_DIRS
michael@0 198 rv = GetProductDirectory(getter_AddRefs(localFile));
michael@0 199 if (NS_SUCCEEDED(rv))
michael@0 200 rv = localFile->AppendRelativeNativePath(PLUGINS_DIR_NAME);
michael@0 201 #else
michael@0 202 rv = NS_ERROR_FAILURE;
michael@0 203 #endif
michael@0 204 }
michael@0 205 #ifdef XP_UNIX
michael@0 206 else if (nsCRT::strcmp(prop, NS_SYSTEM_PLUGINS_DIR) == 0) {
michael@0 207 #ifdef ENABLE_SYSTEM_EXTENSION_DIRS
michael@0 208 static const char *const sysLPlgDir =
michael@0 209 #if defined(HAVE_USR_LIB64_DIR) && defined(__LP64__)
michael@0 210 "/usr/lib64/mozilla/plugins";
michael@0 211 #elif defined(__OpenBSD__) || defined (__FreeBSD__)
michael@0 212 "/usr/local/lib/mozilla/plugins";
michael@0 213 #else
michael@0 214 "/usr/lib/mozilla/plugins";
michael@0 215 #endif
michael@0 216 rv = NS_NewNativeLocalFile(nsDependentCString(sysLPlgDir),
michael@0 217 false, getter_AddRefs(localFile));
michael@0 218 #else
michael@0 219 rv = NS_ERROR_FAILURE;
michael@0 220 #endif
michael@0 221 }
michael@0 222 #endif
michael@0 223 #endif
michael@0 224 else if (nsCRT::strcmp(prop, NS_APP_SEARCH_DIR) == 0)
michael@0 225 {
michael@0 226 rv = CloneMozBinDirectory(getter_AddRefs(localFile));
michael@0 227 if (NS_SUCCEEDED(rv))
michael@0 228 rv = localFile->AppendRelativeNativePath(SEARCH_DIR_NAME);
michael@0 229 }
michael@0 230 else if (nsCRT::strcmp(prop, NS_APP_USER_SEARCH_DIR) == 0)
michael@0 231 {
michael@0 232 rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, _retval);
michael@0 233 if (NS_SUCCEEDED(rv))
michael@0 234 rv = (*_retval)->AppendNative(SEARCH_DIR_NAME);
michael@0 235 }
michael@0 236 else if (nsCRT::strcmp(prop, NS_APP_INSTALL_CLEANUP_DIR) == 0)
michael@0 237 {
michael@0 238 // This is cloned so that embeddors will have a hook to override
michael@0 239 // with their own cleanup dir. See bugzilla bug #105087
michael@0 240 rv = CloneMozBinDirectory(getter_AddRefs(localFile));
michael@0 241 }
michael@0 242
michael@0 243 if (localFile && NS_SUCCEEDED(rv))
michael@0 244 return localFile->QueryInterface(NS_GET_IID(nsIFile), (void**)_retval);
michael@0 245
michael@0 246 return rv;
michael@0 247 }
michael@0 248
michael@0 249
michael@0 250 NS_METHOD nsAppFileLocationProvider::CloneMozBinDirectory(nsIFile **aLocalFile)
michael@0 251 {
michael@0 252 if (NS_WARN_IF(!aLocalFile))
michael@0 253 return NS_ERROR_INVALID_ARG;
michael@0 254 nsresult rv;
michael@0 255
michael@0 256 if (!mMozBinDirectory)
michael@0 257 {
michael@0 258 // Get the mozilla bin directory
michael@0 259 // 1. Check the directory service first for NS_XPCOM_CURRENT_PROCESS_DIR
michael@0 260 // This will be set if a directory was passed to NS_InitXPCOM
michael@0 261 // 2. If that doesn't work, set it to be the current process directory
michael@0 262 nsCOMPtr<nsIProperties>
michael@0 263 directoryService(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv));
michael@0 264 if (NS_FAILED(rv))
michael@0 265 return rv;
michael@0 266
michael@0 267 rv = directoryService->Get(NS_XPCOM_CURRENT_PROCESS_DIR, NS_GET_IID(nsIFile), getter_AddRefs(mMozBinDirectory));
michael@0 268 if (NS_FAILED(rv)) {
michael@0 269 rv = directoryService->Get(NS_OS_CURRENT_PROCESS_DIR, NS_GET_IID(nsIFile), getter_AddRefs(mMozBinDirectory));
michael@0 270 if (NS_FAILED(rv))
michael@0 271 return rv;
michael@0 272 }
michael@0 273 }
michael@0 274
michael@0 275 nsCOMPtr<nsIFile> aFile;
michael@0 276 rv = mMozBinDirectory->Clone(getter_AddRefs(aFile));
michael@0 277 if (NS_FAILED(rv))
michael@0 278 return rv;
michael@0 279
michael@0 280 NS_IF_ADDREF(*aLocalFile = aFile);
michael@0 281 return NS_OK;
michael@0 282 }
michael@0 283
michael@0 284
michael@0 285 //----------------------------------------------------------------------------------------
michael@0 286 // GetProductDirectory - Gets the directory which contains the application data folder
michael@0 287 //
michael@0 288 // UNIX and WIN : <App Folder>/TorBrowser/Data/Browser
michael@0 289 // Mac : <App Folder>/../../TorBrowser/Data/Browser
michael@0 290 //----------------------------------------------------------------------------------------
michael@0 291 NS_METHOD nsAppFileLocationProvider::GetProductDirectory(nsIFile **aLocalFile, bool aLocal)
michael@0 292 {
michael@0 293 if (NS_WARN_IF(!aLocalFile))
michael@0 294 return NS_ERROR_INVALID_ARG;
michael@0 295
michael@0 296 nsresult rv;
michael@0 297 bool exists;
michael@0 298 nsCOMPtr<nsIFile> localDir;
michael@0 299
michael@0 300 rv = CloneMozBinDirectory(getter_AddRefs(localDir));
michael@0 301 NS_ENSURE_SUCCESS(rv, rv);
michael@0 302
michael@0 303 int levelsToRemove = 1; // In FF21+, bin dir points to browser subdirectory.
michael@0 304 #if defined(XP_MACOSX)
michael@0 305 levelsToRemove += 2;
michael@0 306 #endif
michael@0 307 while (localDir && (levelsToRemove > 0)) {
michael@0 308 // When crawling up the hierarchy, components named "." do not count.
michael@0 309 nsAutoCString removedName;
michael@0 310 rv = localDir->GetNativeLeafName(removedName);
michael@0 311 NS_ENSURE_SUCCESS(rv, rv);
michael@0 312 bool didRemove = !removedName.Equals(".");
michael@0 313
michael@0 314 // Remove a directory component.
michael@0 315 nsCOMPtr<nsIFile> parentDir;
michael@0 316 rv = localDir->GetParent(getter_AddRefs(parentDir));
michael@0 317 NS_ENSURE_SUCCESS(rv, rv);
michael@0 318 localDir = parentDir;
michael@0 319
michael@0 320 if (didRemove)
michael@0 321 --levelsToRemove;
michael@0 322 }
michael@0 323
michael@0 324 if (!localDir)
michael@0 325 return NS_ERROR_FAILURE;
michael@0 326
michael@0 327 rv = localDir->AppendRelativeNativePath(NS_LITERAL_CSTRING("TorBrowser"
michael@0 328 XPCOM_FILE_PATH_SEPARATOR "Data"
michael@0 329 XPCOM_FILE_PATH_SEPARATOR "Browser"));
michael@0 330 NS_ENSURE_SUCCESS(rv, rv);
michael@0 331
michael@0 332 if (aLocal) {
michael@0 333 rv = localDir->AppendNative(NS_LITERAL_CSTRING("Caches"));
michael@0 334 NS_ENSURE_SUCCESS(rv, rv);
michael@0 335 }
michael@0 336
michael@0 337 rv = localDir->Exists(&exists);
michael@0 338
michael@0 339 if (NS_SUCCEEDED(rv) && !exists)
michael@0 340 rv = localDir->Create(nsIFile::DIRECTORY_TYPE, 0700);
michael@0 341
michael@0 342 if (NS_FAILED(rv)) return rv;
michael@0 343
michael@0 344 *aLocalFile = localDir;
michael@0 345 NS_ADDREF(*aLocalFile);
michael@0 346
michael@0 347 return rv;
michael@0 348 }
michael@0 349
michael@0 350
michael@0 351 //----------------------------------------------------------------------------------------
michael@0 352 // GetDefaultUserProfileRoot - Gets the directory which contains each user profile dir
michael@0 353 //----------------------------------------------------------------------------------------
michael@0 354 NS_METHOD nsAppFileLocationProvider::GetDefaultUserProfileRoot(nsIFile **aLocalFile, bool aLocal)
michael@0 355 {
michael@0 356 if (NS_WARN_IF(!aLocalFile))
michael@0 357 return NS_ERROR_INVALID_ARG;
michael@0 358
michael@0 359 nsresult rv;
michael@0 360 nsCOMPtr<nsIFile> localDir;
michael@0 361
michael@0 362 rv = GetProductDirectory(getter_AddRefs(localDir), aLocal);
michael@0 363 if (NS_FAILED(rv)) return rv;
michael@0 364
michael@0 365 *aLocalFile = localDir;
michael@0 366 NS_ADDREF(*aLocalFile);
michael@0 367
michael@0 368 return rv;
michael@0 369 }
michael@0 370
michael@0 371 //*****************************************************************************
michael@0 372 // nsAppFileLocationProvider::nsIDirectoryServiceProvider2
michael@0 373 //*****************************************************************************
michael@0 374
michael@0 375 class nsAppDirectoryEnumerator : public nsISimpleEnumerator
michael@0 376 {
michael@0 377 public:
michael@0 378 NS_DECL_ISUPPORTS
michael@0 379
michael@0 380 /**
michael@0 381 * aKeyList is a null-terminated list of properties which are provided by aProvider
michael@0 382 * They do not need to be publicly defined keys.
michael@0 383 */
michael@0 384 nsAppDirectoryEnumerator(nsIDirectoryServiceProvider *aProvider,
michael@0 385 const char* aKeyList[]) :
michael@0 386 mProvider(aProvider),
michael@0 387 mCurrentKey(aKeyList)
michael@0 388 {
michael@0 389 }
michael@0 390
michael@0 391 NS_IMETHOD HasMoreElements(bool *result)
michael@0 392 {
michael@0 393 while (!mNext && *mCurrentKey)
michael@0 394 {
michael@0 395 bool dontCare;
michael@0 396 nsCOMPtr<nsIFile> testFile;
michael@0 397 (void)mProvider->GetFile(*mCurrentKey++, &dontCare, getter_AddRefs(testFile));
michael@0 398 // Don't return a file which does not exist.
michael@0 399 bool exists;
michael@0 400 if (testFile && NS_SUCCEEDED(testFile->Exists(&exists)) && exists)
michael@0 401 mNext = testFile;
michael@0 402 }
michael@0 403 *result = mNext != nullptr;
michael@0 404 return NS_OK;
michael@0 405 }
michael@0 406
michael@0 407 NS_IMETHOD GetNext(nsISupports **result)
michael@0 408 {
michael@0 409 if (NS_WARN_IF(!result))
michael@0 410 return NS_ERROR_INVALID_ARG;
michael@0 411 *result = nullptr;
michael@0 412
michael@0 413 bool hasMore;
michael@0 414 HasMoreElements(&hasMore);
michael@0 415 if (!hasMore)
michael@0 416 return NS_ERROR_FAILURE;
michael@0 417
michael@0 418 *result = mNext;
michael@0 419 NS_IF_ADDREF(*result);
michael@0 420 mNext = nullptr;
michael@0 421
michael@0 422 return *result ? NS_OK : NS_ERROR_FAILURE;
michael@0 423 }
michael@0 424
michael@0 425 // Virtual destructor since subclass nsPathsDirectoryEnumerator
michael@0 426 // does not re-implement Release()
michael@0 427
michael@0 428 virtual ~nsAppDirectoryEnumerator()
michael@0 429 {
michael@0 430 }
michael@0 431
michael@0 432 protected:
michael@0 433 nsIDirectoryServiceProvider *mProvider;
michael@0 434 const char** mCurrentKey;
michael@0 435 nsCOMPtr<nsIFile> mNext;
michael@0 436 };
michael@0 437
michael@0 438 NS_IMPL_ISUPPORTS(nsAppDirectoryEnumerator, nsISimpleEnumerator)
michael@0 439
michael@0 440 /* nsPathsDirectoryEnumerator and PATH_SEPARATOR
michael@0 441 * are not used on MacOS/X. */
michael@0 442
michael@0 443 #if defined(XP_WIN) /* Win32 */
michael@0 444 #define PATH_SEPARATOR ';'
michael@0 445 #else
michael@0 446 #define PATH_SEPARATOR ':'
michael@0 447 #endif
michael@0 448
michael@0 449 class nsPathsDirectoryEnumerator : public nsAppDirectoryEnumerator
michael@0 450 {
michael@0 451 public:
michael@0 452 /**
michael@0 453 * aKeyList is a null-terminated list.
michael@0 454 * The first element is a path list.
michael@0 455 * The remainder are properties provided by aProvider.
michael@0 456 * They do not need to be publicly defined keys.
michael@0 457 */
michael@0 458 nsPathsDirectoryEnumerator(nsIDirectoryServiceProvider *aProvider,
michael@0 459 const char* aKeyList[]) :
michael@0 460 nsAppDirectoryEnumerator(aProvider, aKeyList+1),
michael@0 461 mEndPath(aKeyList[0])
michael@0 462 {
michael@0 463 }
michael@0 464
michael@0 465 NS_IMETHOD HasMoreElements(bool *result)
michael@0 466 {
michael@0 467 if (mEndPath)
michael@0 468 while (!mNext && *mEndPath)
michael@0 469 {
michael@0 470 const char *pathVar = mEndPath;
michael@0 471
michael@0 472 // skip PATH_SEPARATORs at the begining of the mEndPath
michael@0 473 while (*pathVar == PATH_SEPARATOR) pathVar++;
michael@0 474
michael@0 475 do { ++mEndPath; } while (*mEndPath && *mEndPath != PATH_SEPARATOR);
michael@0 476
michael@0 477 nsCOMPtr<nsIFile> localFile;
michael@0 478 NS_NewNativeLocalFile(Substring(pathVar, mEndPath),
michael@0 479 true,
michael@0 480 getter_AddRefs(localFile));
michael@0 481 if (*mEndPath == PATH_SEPARATOR)
michael@0 482 ++mEndPath;
michael@0 483 // Don't return a "file" (directory) which does not exist.
michael@0 484 bool exists;
michael@0 485 if (localFile &&
michael@0 486 NS_SUCCEEDED(localFile->Exists(&exists)) &&
michael@0 487 exists)
michael@0 488 mNext = localFile;
michael@0 489 }
michael@0 490 if (mNext)
michael@0 491 *result = true;
michael@0 492 else
michael@0 493 nsAppDirectoryEnumerator::HasMoreElements(result);
michael@0 494
michael@0 495 return NS_OK;
michael@0 496 }
michael@0 497
michael@0 498 protected:
michael@0 499 const char *mEndPath;
michael@0 500 };
michael@0 501
michael@0 502 NS_IMETHODIMP
michael@0 503 nsAppFileLocationProvider::GetFiles(const char *prop, nsISimpleEnumerator **_retval)
michael@0 504 {
michael@0 505 if (NS_WARN_IF(!_retval))
michael@0 506 return NS_ERROR_INVALID_ARG;
michael@0 507 *_retval = nullptr;
michael@0 508 nsresult rv = NS_ERROR_FAILURE;
michael@0 509
michael@0 510 if (!nsCRT::strcmp(prop, NS_APP_PLUGINS_DIR_LIST))
michael@0 511 {
michael@0 512 #ifdef MOZ_WIDGET_COCOA
michael@0 513 // As of Java for Mac OS X 10.5 Update 10, Apple has (in effect) deprecated Java Plugin2 on
michael@0 514 // on OS X 10.5, and removed the soft link to it from /Library/Internet Plug-Ins/. Java
michael@0 515 // Plugin2 is still present and usable, but there are no longer any links to it in the
michael@0 516 // "normal" locations. So we won't be able to find it unless we look in the "non-normal"
michael@0 517 // location where it actually is. Safari can use the WebKit-specific JavaPluginCocoa.bundle,
michael@0 518 // which (of course) is still fully supported on OS X 10.5. But we have no alternative to
michael@0 519 // using Java Plugin2. For more information see bug 668639.
michael@0 520 static const char* keys[] = { NS_APP_PLUGINS_DIR, NS_MACOSX_USER_PLUGIN_DIR,
michael@0 521 NS_MACOSX_LOCAL_PLUGIN_DIR,
michael@0 522 IsOSXLeopard() ? NS_MACOSX_JAVA2_PLUGIN_DIR : nullptr, nullptr };
michael@0 523 *_retval = new nsAppDirectoryEnumerator(this, keys);
michael@0 524 #else
michael@0 525 #ifdef XP_UNIX
michael@0 526 static const char* keys[] = { nullptr, NS_USER_PLUGINS_DIR, NS_APP_PLUGINS_DIR, NS_SYSTEM_PLUGINS_DIR, nullptr };
michael@0 527 #else
michael@0 528 static const char* keys[] = { nullptr, NS_USER_PLUGINS_DIR, NS_APP_PLUGINS_DIR, nullptr };
michael@0 529 #endif
michael@0 530 if (!keys[0] && !(keys[0] = PR_GetEnv("MOZ_PLUGIN_PATH"))) {
michael@0 531 static const char nullstr = 0;
michael@0 532 keys[0] = &nullstr;
michael@0 533 }
michael@0 534 *_retval = new nsPathsDirectoryEnumerator(this, keys);
michael@0 535 #endif
michael@0 536 NS_IF_ADDREF(*_retval);
michael@0 537 rv = *_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
michael@0 538 }
michael@0 539 if (!nsCRT::strcmp(prop, NS_APP_SEARCH_DIR_LIST))
michael@0 540 {
michael@0 541 static const char* keys[] = { nullptr, NS_APP_SEARCH_DIR, NS_APP_USER_SEARCH_DIR, nullptr };
michael@0 542 if (!keys[0] && !(keys[0] = PR_GetEnv("MOZ_SEARCH_ENGINE_PATH"))) {
michael@0 543 static const char nullstr = 0;
michael@0 544 keys[0] = &nullstr;
michael@0 545 }
michael@0 546 *_retval = new nsPathsDirectoryEnumerator(this, keys);
michael@0 547 NS_IF_ADDREF(*_retval);
michael@0 548 rv = *_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
michael@0 549 }
michael@0 550 return rv;
michael@0 551 }
michael@0 552
michael@0 553 #if defined(MOZ_WIDGET_COCOA)
michael@0 554 bool
michael@0 555 nsAppFileLocationProvider::IsOSXLeopard()
michael@0 556 {
michael@0 557 static SInt32 version = 0;
michael@0 558
michael@0 559 if (!version) {
michael@0 560 OSErr err = ::Gestalt(gestaltSystemVersion, &version);
michael@0 561 if (err != noErr) {
michael@0 562 version = 0;
michael@0 563 } else {
michael@0 564 version &= 0xFFFF; // The system version is in the low order word
michael@0 565 }
michael@0 566 }
michael@0 567
michael@0 568 return ((version >= 0x1050) && (version < 0x1060));
michael@0 569 }
michael@0 570 #endif

mercurial