xpcom/io/nsDirectoryService.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/xpcom/io/nsDirectoryService.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,894 @@
     1.4 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
     1.5 + * vim: sw=4 ts=4 sts=4 et
     1.6 + * This Source Code Form is subject to the terms of the Mozilla Public
     1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.9 +
    1.10 +#include "mozilla/ArrayUtils.h"
    1.11 +
    1.12 +#include "nsCOMPtr.h"
    1.13 +#include "nsAutoPtr.h"
    1.14 +#include "nsDirectoryService.h"
    1.15 +#include "nsDirectoryServiceDefs.h"
    1.16 +#include "nsLocalFile.h"
    1.17 +#include "nsDebug.h"
    1.18 +#include "nsStaticAtom.h"
    1.19 +#include "nsEnumeratorUtils.h"
    1.20 +
    1.21 +#include "nsICategoryManager.h"
    1.22 +#include "nsISimpleEnumerator.h"
    1.23 +#include "nsIStringEnumerator.h"
    1.24 +
    1.25 +#if defined(XP_WIN)
    1.26 +#include <windows.h>
    1.27 +#include <shlobj.h>
    1.28 +#include <stdlib.h>
    1.29 +#include <stdio.h>
    1.30 +#elif defined(XP_UNIX)
    1.31 +#include <unistd.h>
    1.32 +#include <stdlib.h>
    1.33 +#include <sys/param.h>
    1.34 +#include "prenv.h"
    1.35 +#ifdef MOZ_WIDGET_COCOA
    1.36 +#include <CoreServices/CoreServices.h>
    1.37 +#include <Carbon/Carbon.h>
    1.38 +#endif
    1.39 +#endif
    1.40 +
    1.41 +#include "SpecialSystemDirectory.h"
    1.42 +#include "nsAppFileLocationProvider.h"
    1.43 +
    1.44 +using namespace mozilla;
    1.45 +
    1.46 +// define home directory
    1.47 +// For Windows platform, We are choosing Appdata folder as HOME
    1.48 +#if defined (XP_WIN)
    1.49 +#define HOME_DIR NS_WIN_APPDATA_DIR
    1.50 +#elif defined (MOZ_WIDGET_COCOA)
    1.51 +#define HOME_DIR NS_OSX_HOME_DIR
    1.52 +#elif defined (XP_UNIX)
    1.53 +#define HOME_DIR NS_UNIX_HOME_DIR
    1.54 +#endif
    1.55 +
    1.56 +//----------------------------------------------------------------------------------------
    1.57 +nsresult 
    1.58 +nsDirectoryService::GetCurrentProcessDirectory(nsIFile** aFile)
    1.59 +//----------------------------------------------------------------------------------------
    1.60 +{
    1.61 +    if (NS_WARN_IF(!aFile))
    1.62 +        return NS_ERROR_INVALID_ARG;
    1.63 +    *aFile = nullptr;
    1.64 +    
    1.65 +   //  Set the component registry location:
    1.66 +    if (!gService)
    1.67 +        return NS_ERROR_FAILURE;
    1.68 +
    1.69 +    nsresult rv; 
    1.70 + 
    1.71 +    nsCOMPtr<nsIProperties> dirService;
    1.72 +    rv = nsDirectoryService::Create(nullptr, 
    1.73 +                                    NS_GET_IID(nsIProperties), 
    1.74 +                                    getter_AddRefs(dirService));  // needs to be around for life of product
    1.75 +    if (NS_FAILED(rv))
    1.76 +        return rv;
    1.77 +
    1.78 +    if (dirService)
    1.79 +    {
    1.80 +      nsCOMPtr <nsIFile> aLocalFile;
    1.81 +      dirService->Get(NS_XPCOM_INIT_CURRENT_PROCESS_DIR, NS_GET_IID(nsIFile), getter_AddRefs(aLocalFile));
    1.82 +      if (aLocalFile)
    1.83 +      {
    1.84 +        *aFile = aLocalFile;
    1.85 +        NS_ADDREF(*aFile);
    1.86 +        return NS_OK;
    1.87 +      }
    1.88 +    }
    1.89 +
    1.90 +    nsLocalFile* localFile = new nsLocalFile;
    1.91 +
    1.92 +    if (localFile == nullptr)
    1.93 +        return NS_ERROR_OUT_OF_MEMORY;
    1.94 +    NS_ADDREF(localFile);
    1.95 +
    1.96 +
    1.97 +
    1.98 +#ifdef XP_WIN
    1.99 +    wchar_t buf[MAX_PATH + 1];
   1.100 +    SetLastError(ERROR_SUCCESS);
   1.101 +    if (GetModuleFileNameW(0, buf, mozilla::ArrayLength(buf)) &&
   1.102 +        GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
   1.103 +        // chop off the executable name by finding the rightmost backslash
   1.104 +        wchar_t* lastSlash = wcsrchr(buf, L'\\');
   1.105 +        if (lastSlash)
   1.106 +            *(lastSlash + 1) = L'\0';
   1.107 +
   1.108 +        localFile->InitWithPath(nsDependentString(buf));
   1.109 +        *aFile = localFile;
   1.110 +        return NS_OK;
   1.111 +    }
   1.112 +
   1.113 +#elif defined(MOZ_WIDGET_COCOA)
   1.114 +    // Works even if we're not bundled.
   1.115 +    CFBundleRef appBundle = CFBundleGetMainBundle();
   1.116 +    if (appBundle != nullptr)
   1.117 +    {
   1.118 +        CFURLRef bundleURL = CFBundleCopyExecutableURL(appBundle);
   1.119 +        if (bundleURL != nullptr)
   1.120 +        {
   1.121 +            CFURLRef parentURL = CFURLCreateCopyDeletingLastPathComponent(kCFAllocatorDefault, bundleURL);
   1.122 +            if (parentURL)
   1.123 +            {
   1.124 +                // Pass true for the "resolveAgainstBase" arg to CFURLGetFileSystemRepresentation.
   1.125 +                // This will resolve the relative portion of the CFURL against it base, giving a full
   1.126 +                // path, which CFURLCopyFileSystemPath doesn't do.
   1.127 +                char buffer[PATH_MAX];
   1.128 +                if (CFURLGetFileSystemRepresentation(parentURL, true, (UInt8 *)buffer, sizeof(buffer)))
   1.129 +                {
   1.130 +#ifdef DEBUG_conrad
   1.131 +                    printf("nsDirectoryService - CurrentProcessDir is: %s\n", buffer);
   1.132 +#endif
   1.133 +                    rv = localFile->InitWithNativePath(nsDependentCString(buffer));
   1.134 +                    if (NS_SUCCEEDED(rv))
   1.135 +                        *aFile = localFile;
   1.136 +                }
   1.137 +                CFRelease(parentURL);
   1.138 +            }
   1.139 +            CFRelease(bundleURL);
   1.140 +        }
   1.141 +    }
   1.142 +    
   1.143 +    NS_ASSERTION(*aFile, "nsDirectoryService - Could not determine CurrentProcessDir.\n");
   1.144 +    if (*aFile)
   1.145 +        return NS_OK;
   1.146 +
   1.147 +#elif defined(XP_UNIX)
   1.148 +
   1.149 +    // In the absence of a good way to get the executable directory let
   1.150 +    // us try this for unix:
   1.151 +    //    - if MOZILLA_FIVE_HOME is defined, that is it
   1.152 +    //    - else give the current directory
   1.153 +    char buf[MAXPATHLEN];
   1.154 +
   1.155 +    // The MOZ_DEFAULT_MOZILLA_FIVE_HOME variable can be set at configure time with
   1.156 +    // a --with-default-mozilla-five-home=foo autoconf flag.
   1.157 +    // 
   1.158 +    // The idea here is to allow for builds that have a default MOZILLA_FIVE_HOME
   1.159 +    // regardless of the environment.  This makes it easier to write apps that
   1.160 +    // embed mozilla without having to worry about setting up the environment 
   1.161 +    //
   1.162 +    // We do this by putenv()ing the default value into the environment.  Note that
   1.163 +    // we only do this if it is not already set.
   1.164 +#ifdef MOZ_DEFAULT_MOZILLA_FIVE_HOME
   1.165 +    const char *home = PR_GetEnv("MOZILLA_FIVE_HOME");
   1.166 +    if (!home || !*home)
   1.167 +    {
   1.168 +        putenv("MOZILLA_FIVE_HOME=" MOZ_DEFAULT_MOZILLA_FIVE_HOME);
   1.169 +    }
   1.170 +#endif
   1.171 +
   1.172 +    char *moz5 = PR_GetEnv("MOZILLA_FIVE_HOME");
   1.173 +    if (moz5 && *moz5)
   1.174 +    {
   1.175 +        if (realpath(moz5, buf)) {
   1.176 +            localFile->InitWithNativePath(nsDependentCString(buf));
   1.177 +            *aFile = localFile;
   1.178 +            return NS_OK;
   1.179 +        }
   1.180 +    }
   1.181 +#if defined(DEBUG)
   1.182 +    static bool firstWarning = true;
   1.183 +
   1.184 +    if((!moz5 || !*moz5) && firstWarning) {
   1.185 +        // Warn that MOZILLA_FIVE_HOME not set, once.
   1.186 +        printf("Warning: MOZILLA_FIVE_HOME not set.\n");
   1.187 +        firstWarning = false;
   1.188 +    }
   1.189 +#endif /* DEBUG */
   1.190 +
   1.191 +    // Fall back to current directory.
   1.192 +    if (getcwd(buf, sizeof(buf)))
   1.193 +    {
   1.194 +        localFile->InitWithNativePath(nsDependentCString(buf));
   1.195 +        *aFile = localFile;
   1.196 +        return NS_OK;
   1.197 +    }
   1.198 +
   1.199 +#endif
   1.200 +    
   1.201 +    NS_RELEASE(localFile);
   1.202 +
   1.203 +    NS_ERROR("unable to get current process directory");
   1.204 +    return NS_ERROR_FAILURE;
   1.205 +} // GetCurrentProcessDirectory()
   1.206 +
   1.207 +nsDirectoryService* nsDirectoryService::gService = nullptr;
   1.208 +
   1.209 +nsDirectoryService::nsDirectoryService()
   1.210 +    : mHashtable(256)
   1.211 +{
   1.212 +}
   1.213 +
   1.214 +nsresult
   1.215 +nsDirectoryService::Create(nsISupports *outer, REFNSIID aIID, void **aResult)
   1.216 +{
   1.217 +    if (NS_WARN_IF(!aResult))
   1.218 +        return NS_ERROR_INVALID_ARG;
   1.219 +    if (NS_WARN_IF(outer))
   1.220 +        return NS_ERROR_NO_AGGREGATION;
   1.221 +
   1.222 +    if (!gService)
   1.223 +    {
   1.224 +        return NS_ERROR_NOT_INITIALIZED;
   1.225 +    }
   1.226 +
   1.227 +    return gService->QueryInterface(aIID, aResult);
   1.228 +}
   1.229 +
   1.230 +#define DIR_ATOM(name_, value_) nsIAtom* nsDirectoryService::name_ = nullptr;
   1.231 +#include "nsDirectoryServiceAtomList.h"
   1.232 +#undef DIR_ATOM
   1.233 +
   1.234 +#define DIR_ATOM(name_, value_) NS_STATIC_ATOM_BUFFER(name_##_buffer, value_)
   1.235 +#include "nsDirectoryServiceAtomList.h"
   1.236 +#undef DIR_ATOM
   1.237 +
   1.238 +static const nsStaticAtom directory_atoms[] = {
   1.239 +#define DIR_ATOM(name_, value_) NS_STATIC_ATOM(name_##_buffer, &nsDirectoryService::name_),
   1.240 +#include "nsDirectoryServiceAtomList.h"
   1.241 +#undef DIR_ATOM
   1.242 +};    
   1.243 +
   1.244 +NS_IMETHODIMP
   1.245 +nsDirectoryService::Init()
   1.246 +{
   1.247 +    NS_NOTREACHED("nsDirectoryService::Init() for internal use only!");
   1.248 +    return NS_OK;
   1.249 +}
   1.250 +
   1.251 +void
   1.252 +nsDirectoryService::RealInit()
   1.253 +{
   1.254 +    NS_ASSERTION(!gService, 
   1.255 +                 "nsDirectoryService::RealInit Mustn't initialize twice!");
   1.256 +
   1.257 +    nsRefPtr<nsDirectoryService> self = new nsDirectoryService();
   1.258 +
   1.259 +    NS_RegisterStaticAtoms(directory_atoms);
   1.260 +    
   1.261 +    // Let the list hold the only reference to the provider.
   1.262 +    nsAppFileLocationProvider *defaultProvider = new nsAppFileLocationProvider;
   1.263 +    self->mProviders.AppendElement(defaultProvider);
   1.264 +
   1.265 +    self.swap(gService);
   1.266 +}
   1.267 +
   1.268 +nsDirectoryService::~nsDirectoryService()
   1.269 +{
   1.270 +}
   1.271 +
   1.272 +NS_IMPL_ISUPPORTS(nsDirectoryService, nsIProperties, nsIDirectoryService, nsIDirectoryServiceProvider, nsIDirectoryServiceProvider2)
   1.273 +
   1.274 +
   1.275 +NS_IMETHODIMP
   1.276 +nsDirectoryService::Undefine(const char* prop)
   1.277 +{
   1.278 +    if (NS_WARN_IF(!prop))
   1.279 +        return NS_ERROR_INVALID_ARG;
   1.280 +
   1.281 +    nsDependentCString key(prop);
   1.282 +    if (!mHashtable.Get(key, nullptr))
   1.283 +        return NS_ERROR_FAILURE;
   1.284 +
   1.285 +    mHashtable.Remove(key);
   1.286 +    return NS_OK;
   1.287 + }
   1.288 +
   1.289 +NS_IMETHODIMP
   1.290 +nsDirectoryService::GetKeys(uint32_t *count, char ***keys)
   1.291 +{
   1.292 +    return NS_ERROR_NOT_IMPLEMENTED;
   1.293 +}
   1.294 +
   1.295 +struct FileData
   1.296 +{
   1.297 +  FileData(const char* aProperty,
   1.298 +           const nsIID& aUUID) :
   1.299 +    property(aProperty),
   1.300 +    data(nullptr),
   1.301 +    persistent(true),
   1.302 +    uuid(aUUID) {}
   1.303 +    
   1.304 +  const char*   property;
   1.305 +  nsISupports*  data;
   1.306 +  bool          persistent;
   1.307 +  const nsIID&  uuid;
   1.308 +};
   1.309 +
   1.310 +static bool FindProviderFile(nsIDirectoryServiceProvider* aElement,
   1.311 +                             FileData* aData)
   1.312 +{
   1.313 +  nsresult rv;
   1.314 +  if (aData->uuid.Equals(NS_GET_IID(nsISimpleEnumerator))) {
   1.315 +      // Not all providers implement this iface
   1.316 +      nsCOMPtr<nsIDirectoryServiceProvider2> prov2 = do_QueryInterface(aElement);
   1.317 +      if (prov2)
   1.318 +      {
   1.319 +          nsCOMPtr<nsISimpleEnumerator> newFiles;
   1.320 +          rv = prov2->GetFiles(aData->property, getter_AddRefs(newFiles));
   1.321 +          if (NS_SUCCEEDED(rv) && newFiles) {
   1.322 +              if (aData->data) {
   1.323 +                  nsCOMPtr<nsISimpleEnumerator> unionFiles;
   1.324 +
   1.325 +                  NS_NewUnionEnumerator(getter_AddRefs(unionFiles),
   1.326 +                                        (nsISimpleEnumerator*) aData->data, newFiles);
   1.327 +
   1.328 +                  if (unionFiles)
   1.329 +                      unionFiles.swap(* (nsISimpleEnumerator**) &aData->data);
   1.330 +              }
   1.331 +              else
   1.332 +              {
   1.333 +                  NS_ADDREF(aData->data = newFiles);
   1.334 +              }
   1.335 +                  
   1.336 +              aData->persistent = false; // Enumerators can never be persistent
   1.337 +              return rv == NS_SUCCESS_AGGREGATE_RESULT;
   1.338 +          }
   1.339 +      }
   1.340 +  }
   1.341 +  else
   1.342 +  {
   1.343 +      rv = aElement->GetFile(aData->property, &aData->persistent,
   1.344 +                             (nsIFile **)&aData->data);
   1.345 +      if (NS_SUCCEEDED(rv) && aData->data)
   1.346 +          return false;
   1.347 +  }
   1.348 +
   1.349 +  return true;
   1.350 +}
   1.351 +
   1.352 +NS_IMETHODIMP
   1.353 +nsDirectoryService::Get(const char* prop, const nsIID & uuid, void* *result)
   1.354 +{
   1.355 +    if (NS_WARN_IF(!prop))
   1.356 +        return NS_ERROR_INVALID_ARG;
   1.357 +
   1.358 +    nsDependentCString key(prop);
   1.359 +
   1.360 +    nsCOMPtr<nsIFile> cachedFile = mHashtable.Get(key);
   1.361 +
   1.362 +    if (cachedFile) {
   1.363 +        nsCOMPtr<nsIFile> cloneFile;
   1.364 +        cachedFile->Clone(getter_AddRefs(cloneFile));
   1.365 +        return cloneFile->QueryInterface(uuid, result);
   1.366 +    }
   1.367 +
   1.368 +    // it is not one of our defaults, lets check any providers
   1.369 +    FileData fileData(prop, uuid);
   1.370 +
   1.371 +    for (int32_t i = mProviders.Length() - 1; i >= 0; i--) {
   1.372 +        if (!FindProviderFile(mProviders[i], &fileData)) {
   1.373 +            break;
   1.374 +        }
   1.375 +    }
   1.376 +    if (fileData.data)
   1.377 +    {
   1.378 +        if (fileData.persistent)
   1.379 +        {
   1.380 +            Set(prop, static_cast<nsIFile*>(fileData.data));
   1.381 +        }
   1.382 +        nsresult rv = (fileData.data)->QueryInterface(uuid, result);
   1.383 +        NS_RELEASE(fileData.data);  // addref occurs in FindProviderFile()
   1.384 +        return rv;
   1.385 +    }
   1.386 +
   1.387 +    FindProviderFile(static_cast<nsIDirectoryServiceProvider*>(this), &fileData);
   1.388 +    if (fileData.data)
   1.389 +    {
   1.390 +        if (fileData.persistent)
   1.391 +        {
   1.392 +            Set(prop, static_cast<nsIFile*>(fileData.data));
   1.393 +        }
   1.394 +        nsresult rv = (fileData.data)->QueryInterface(uuid, result);
   1.395 +        NS_RELEASE(fileData.data);  // addref occurs in FindProviderFile()
   1.396 +        return rv;
   1.397 +    }
   1.398 +
   1.399 +    return NS_ERROR_FAILURE;
   1.400 +}
   1.401 +
   1.402 +NS_IMETHODIMP
   1.403 +nsDirectoryService::Set(const char* prop, nsISupports* value)
   1.404 +{
   1.405 +    if (NS_WARN_IF(!prop))
   1.406 +        return NS_ERROR_INVALID_ARG;
   1.407 +
   1.408 +    nsDependentCString key(prop);
   1.409 +    if (mHashtable.Get(key, nullptr) || !value) {
   1.410 +        return NS_ERROR_FAILURE;
   1.411 +    }
   1.412 +
   1.413 +    nsCOMPtr<nsIFile> ourFile = do_QueryInterface(value);
   1.414 +    if (ourFile) {
   1.415 +      nsCOMPtr<nsIFile> cloneFile;
   1.416 +      ourFile->Clone (getter_AddRefs (cloneFile));
   1.417 +      mHashtable.Put(key, cloneFile);
   1.418 +
   1.419 +      return NS_OK;
   1.420 +    }
   1.421 +
   1.422 +    return NS_ERROR_FAILURE;
   1.423 +}
   1.424 +
   1.425 +NS_IMETHODIMP
   1.426 +nsDirectoryService::Has(const char *prop, bool *_retval)
   1.427 +{
   1.428 +    if (NS_WARN_IF(!prop))
   1.429 +        return NS_ERROR_INVALID_ARG;
   1.430 +
   1.431 +    *_retval = false;
   1.432 +    nsCOMPtr<nsIFile> value;
   1.433 +    nsresult rv = Get(prop, NS_GET_IID(nsIFile), getter_AddRefs(value));
   1.434 +    if (NS_FAILED(rv))
   1.435 +        return NS_OK;
   1.436 +    
   1.437 +    if (value)
   1.438 +    {
   1.439 +        *_retval = true;
   1.440 +    }
   1.441 +    
   1.442 +    return rv;
   1.443 +}
   1.444 +
   1.445 +NS_IMETHODIMP
   1.446 +nsDirectoryService::RegisterProvider(nsIDirectoryServiceProvider *prov)
   1.447 +{
   1.448 +    if (!prov)
   1.449 +        return NS_ERROR_FAILURE;
   1.450 +
   1.451 +    mProviders.AppendElement(prov);
   1.452 +    return NS_OK;
   1.453 +}
   1.454 +
   1.455 +void
   1.456 +nsDirectoryService::RegisterCategoryProviders()
   1.457 +{
   1.458 +    nsCOMPtr<nsICategoryManager> catman
   1.459 +        (do_GetService(NS_CATEGORYMANAGER_CONTRACTID));
   1.460 +    if (!catman)
   1.461 +        return;
   1.462 +
   1.463 +    nsCOMPtr<nsISimpleEnumerator> entries;
   1.464 +    catman->EnumerateCategory(XPCOM_DIRECTORY_PROVIDER_CATEGORY,
   1.465 +                              getter_AddRefs(entries));
   1.466 +
   1.467 +    nsCOMPtr<nsIUTF8StringEnumerator> strings(do_QueryInterface(entries));
   1.468 +    if (!strings)
   1.469 +        return;
   1.470 +
   1.471 +    bool more;
   1.472 +    while (NS_SUCCEEDED(strings->HasMore(&more)) && more) {
   1.473 +        nsAutoCString entry;
   1.474 +        strings->GetNext(entry);
   1.475 +
   1.476 +        nsXPIDLCString contractID;
   1.477 +        catman->GetCategoryEntry(XPCOM_DIRECTORY_PROVIDER_CATEGORY, entry.get(), getter_Copies(contractID));
   1.478 +
   1.479 +        if (contractID) {
   1.480 +            nsCOMPtr<nsIDirectoryServiceProvider> provider = do_GetService(contractID.get());
   1.481 +            if (provider)
   1.482 +                RegisterProvider(provider);
   1.483 +        }
   1.484 +    }
   1.485 +}
   1.486 +
   1.487 +NS_IMETHODIMP
   1.488 +nsDirectoryService::UnregisterProvider(nsIDirectoryServiceProvider *prov)
   1.489 +{
   1.490 +    if (!prov)
   1.491 +        return NS_ERROR_FAILURE;
   1.492 +
   1.493 +    mProviders.RemoveElement(prov);
   1.494 +    return NS_OK;
   1.495 +}
   1.496 +
   1.497 +// DO NOT ADD ANY LOCATIONS TO THIS FUNCTION UNTIL YOU TALK TO: dougt@netscape.com.
   1.498 +// This is meant to be a place of xpcom or system specific file locations, not
   1.499 +// application specific locations.  If you need the later, register a callback for
   1.500 +// your application.  
   1.501 +
   1.502 +NS_IMETHODIMP
   1.503 +nsDirectoryService::GetFile(const char *prop, bool *persistent, nsIFile **_retval)
   1.504 +{
   1.505 +    nsCOMPtr<nsIFile> localFile;
   1.506 +    nsresult rv = NS_ERROR_FAILURE;
   1.507 +
   1.508 +    *_retval = nullptr;
   1.509 +    *persistent = true;
   1.510 +
   1.511 +    nsCOMPtr<nsIAtom> inAtom = do_GetAtom(prop);
   1.512 +
   1.513 +    // check to see if it is one of our defaults
   1.514 +        
   1.515 +    if (inAtom == nsDirectoryService::sCurrentProcess || 
   1.516 +        inAtom == nsDirectoryService::sOS_CurrentProcessDirectory )
   1.517 +    {
   1.518 +        rv = GetCurrentProcessDirectory(getter_AddRefs(localFile));
   1.519 +    }
   1.520 +    
   1.521 +    // Unless otherwise set, the core pieces of the GRE exist
   1.522 +    // in the current process directory.
   1.523 +    else if (inAtom == nsDirectoryService::sGRE_Directory)
   1.524 +    {
   1.525 +        rv = GetCurrentProcessDirectory(getter_AddRefs(localFile));
   1.526 +    }
   1.527 +    else if (inAtom == nsDirectoryService::sOS_DriveDirectory)
   1.528 +    {
   1.529 +        rv = GetSpecialSystemDirectory(OS_DriveDirectory, getter_AddRefs(localFile));
   1.530 +    }
   1.531 +    else if (inAtom == nsDirectoryService::sOS_TemporaryDirectory)
   1.532 +    {
   1.533 +        rv = GetSpecialSystemDirectory(OS_TemporaryDirectory, getter_AddRefs(localFile));
   1.534 +    }
   1.535 +    else if (inAtom == nsDirectoryService::sOS_CurrentProcessDirectory)
   1.536 +    {
   1.537 +        rv = GetSpecialSystemDirectory(OS_CurrentProcessDirectory, getter_AddRefs(localFile)); 
   1.538 +    }
   1.539 +    else if (inAtom == nsDirectoryService::sOS_CurrentWorkingDirectory)
   1.540 +    {
   1.541 +        rv = GetSpecialSystemDirectory(OS_CurrentWorkingDirectory, getter_AddRefs(localFile)); 
   1.542 +    }
   1.543 +       
   1.544 +#if defined(MOZ_WIDGET_COCOA)
   1.545 +    else if (inAtom == nsDirectoryService::sDirectory)
   1.546 +    {
   1.547 +        rv = GetOSXFolderType(kClassicDomain, kSystemFolderType, getter_AddRefs(localFile));
   1.548 +    }
   1.549 +    else if (inAtom == nsDirectoryService::sTrashDirectory)
   1.550 +    {
   1.551 +        rv = GetOSXFolderType(kClassicDomain, kTrashFolderType, getter_AddRefs(localFile));
   1.552 +    }
   1.553 +    else if (inAtom == nsDirectoryService::sStartupDirectory)
   1.554 +    {
   1.555 +        rv = GetOSXFolderType(kClassicDomain, kStartupFolderType, getter_AddRefs(localFile));
   1.556 +    }
   1.557 +    else if (inAtom == nsDirectoryService::sShutdownDirectory)
   1.558 +    {
   1.559 +        rv = GetOSXFolderType(kClassicDomain, kShutdownFolderType, getter_AddRefs(localFile));
   1.560 +    }
   1.561 +    else if (inAtom == nsDirectoryService::sAppleMenuDirectory)
   1.562 +    {
   1.563 +        rv = GetOSXFolderType(kClassicDomain, kAppleMenuFolderType, getter_AddRefs(localFile));
   1.564 +    }
   1.565 +    else if (inAtom == nsDirectoryService::sControlPanelDirectory)
   1.566 +    {
   1.567 +        rv = GetOSXFolderType(kClassicDomain, kControlPanelFolderType, getter_AddRefs(localFile));
   1.568 +    }
   1.569 +    else if (inAtom == nsDirectoryService::sExtensionDirectory)
   1.570 +    {
   1.571 +        rv = GetOSXFolderType(kClassicDomain, kExtensionFolderType, getter_AddRefs(localFile));
   1.572 +    }
   1.573 +    else if (inAtom == nsDirectoryService::sFontsDirectory)
   1.574 +    {
   1.575 +        rv = GetOSXFolderType(kClassicDomain, kFontsFolderType, getter_AddRefs(localFile));
   1.576 +    }
   1.577 +    else if (inAtom == nsDirectoryService::sPreferencesDirectory)
   1.578 +    {
   1.579 +        rv = GetOSXFolderType(kClassicDomain, kPreferencesFolderType, getter_AddRefs(localFile));
   1.580 +    }
   1.581 +    else if (inAtom == nsDirectoryService::sDocumentsDirectory)
   1.582 +    {
   1.583 +        rv = GetOSXFolderType(kClassicDomain, kDocumentsFolderType, getter_AddRefs(localFile));
   1.584 +    }
   1.585 +    else if (inAtom == nsDirectoryService::sInternetSearchDirectory)
   1.586 +    {
   1.587 +        rv = GetOSXFolderType(kClassicDomain, kInternetSearchSitesFolderType, getter_AddRefs(localFile));
   1.588 +    }   
   1.589 +    else if (inAtom == nsDirectoryService::sUserLibDirectory)
   1.590 +    {
   1.591 +        rv = GetOSXFolderType(kUserDomain, kDomainLibraryFolderType, getter_AddRefs(localFile));
   1.592 +    }
   1.593 +    else if (inAtom == nsDirectoryService::sOS_HomeDirectory)
   1.594 +    {
   1.595 +        rv = GetOSXFolderType(kUserDomain, kDomainTopLevelFolderType, getter_AddRefs(localFile));
   1.596 +    }
   1.597 +    else if (inAtom == nsDirectoryService::sDefaultDownloadDirectory)
   1.598 +    {
   1.599 +        // 10.5 and later, we can use kDownloadsFolderType which is defined in
   1.600 +        // Folders.h as "down".  However, in order to support 10.4 still, we
   1.601 +        // cannot use the named constant.  We'll use it's value, and if it
   1.602 +        // fails, fall back to the desktop.
   1.603 +#ifndef kDownloadsFolderType
   1.604 +#define kDownloadsFolderType 'down'
   1.605 +#endif
   1.606 +
   1.607 +        rv = GetOSXFolderType(kUserDomain, kDownloadsFolderType,
   1.608 +                              getter_AddRefs(localFile));
   1.609 +        if (NS_FAILED(rv)) {
   1.610 +            rv = GetOSXFolderType(kUserDomain, kDesktopFolderType,
   1.611 +                                  getter_AddRefs(localFile));
   1.612 +        }
   1.613 +    }
   1.614 +    else if (inAtom == nsDirectoryService::sUserDesktopDirectory ||
   1.615 +             inAtom == nsDirectoryService::sOS_DesktopDirectory)
   1.616 +    {
   1.617 +        rv = GetOSXFolderType(kUserDomain, kDesktopFolderType, getter_AddRefs(localFile));
   1.618 +    }
   1.619 +    else if (inAtom == nsDirectoryService::sLocalDesktopDirectory)
   1.620 +    {
   1.621 +        rv = GetOSXFolderType(kLocalDomain, kDesktopFolderType, getter_AddRefs(localFile));
   1.622 +    }
   1.623 +    else if (inAtom == nsDirectoryService::sUserApplicationsDirectory)
   1.624 +    {
   1.625 +        rv = GetOSXFolderType(kUserDomain, kApplicationsFolderType, getter_AddRefs(localFile));
   1.626 +    }
   1.627 +    else if (inAtom == nsDirectoryService::sLocalApplicationsDirectory)
   1.628 +    {
   1.629 +        rv = GetOSXFolderType(kLocalDomain, kApplicationsFolderType, getter_AddRefs(localFile));
   1.630 +    }
   1.631 +    else if (inAtom == nsDirectoryService::sUserDocumentsDirectory)
   1.632 +    {
   1.633 +        rv = GetOSXFolderType(kUserDomain, kDocumentsFolderType, getter_AddRefs(localFile));
   1.634 +    }
   1.635 +    else if (inAtom == nsDirectoryService::sLocalDocumentsDirectory)
   1.636 +    {
   1.637 +        rv = GetOSXFolderType(kLocalDomain, kDocumentsFolderType, getter_AddRefs(localFile));
   1.638 +    }
   1.639 +    else if (inAtom == nsDirectoryService::sUserInternetPlugInDirectory)
   1.640 +    {
   1.641 +        rv = GetOSXFolderType(kUserDomain, kInternetPlugInFolderType, getter_AddRefs(localFile));
   1.642 +    }
   1.643 +    else if (inAtom == nsDirectoryService::sLocalInternetPlugInDirectory)
   1.644 +    {
   1.645 +        rv = GetOSXFolderType(kLocalDomain, kInternetPlugInFolderType, getter_AddRefs(localFile));
   1.646 +    }
   1.647 +    else if (inAtom == nsDirectoryService::sUserFrameworksDirectory)
   1.648 +    {
   1.649 +        rv = GetOSXFolderType(kUserDomain, kFrameworksFolderType, getter_AddRefs(localFile));
   1.650 +    }
   1.651 +    else if (inAtom == nsDirectoryService::sLocalFrameworksDirectory)
   1.652 +    {
   1.653 +        rv = GetOSXFolderType(kLocalDomain, kFrameworksFolderType, getter_AddRefs(localFile));
   1.654 +    }
   1.655 +    else if (inAtom == nsDirectoryService::sUserPreferencesDirectory)
   1.656 +    {
   1.657 +        rv = GetOSXFolderType(kUserDomain, kPreferencesFolderType, getter_AddRefs(localFile));
   1.658 +    }
   1.659 +    else if (inAtom == nsDirectoryService::sLocalPreferencesDirectory)
   1.660 +    {
   1.661 +        rv = GetOSXFolderType(kLocalDomain, kPreferencesFolderType, getter_AddRefs(localFile));
   1.662 +    }
   1.663 +    else if (inAtom == nsDirectoryService::sPictureDocumentsDirectory)
   1.664 +    {
   1.665 +        rv = GetOSXFolderType(kUserDomain, kPictureDocumentsFolderType, getter_AddRefs(localFile));
   1.666 +    }
   1.667 +    else if (inAtom == nsDirectoryService::sMovieDocumentsDirectory)
   1.668 +    {
   1.669 +        rv = GetOSXFolderType(kUserDomain, kMovieDocumentsFolderType, getter_AddRefs(localFile));
   1.670 +    }
   1.671 +    else if (inAtom == nsDirectoryService::sMusicDocumentsDirectory)
   1.672 +    {
   1.673 +        rv = GetOSXFolderType(kUserDomain, kMusicDocumentsFolderType, getter_AddRefs(localFile));
   1.674 +    }
   1.675 +    else if (inAtom == nsDirectoryService::sInternetSitesDirectory)
   1.676 +    {
   1.677 +        rv = GetOSXFolderType(kUserDomain, kInternetSitesFolderType, getter_AddRefs(localFile));
   1.678 +    }
   1.679 +#elif defined (XP_WIN)
   1.680 +    else if (inAtom == nsDirectoryService::sSystemDirectory)
   1.681 +    {
   1.682 +        rv = GetSpecialSystemDirectory(Win_SystemDirectory, getter_AddRefs(localFile)); 
   1.683 +    }
   1.684 +    else if (inAtom == nsDirectoryService::sWindowsDirectory)
   1.685 +    {
   1.686 +        rv = GetSpecialSystemDirectory(Win_WindowsDirectory, getter_AddRefs(localFile)); 
   1.687 +    }
   1.688 +    else if (inAtom == nsDirectoryService::sWindowsProgramFiles)
   1.689 +    {
   1.690 +        rv = GetSpecialSystemDirectory(Win_ProgramFiles, getter_AddRefs(localFile));
   1.691 +    }
   1.692 +    else if (inAtom == nsDirectoryService::sOS_HomeDirectory)
   1.693 +    {
   1.694 +        rv = GetSpecialSystemDirectory(Win_HomeDirectory, getter_AddRefs(localFile)); 
   1.695 +    }
   1.696 +    else if (inAtom == nsDirectoryService::sDesktop)
   1.697 +    {
   1.698 +        rv = GetSpecialSystemDirectory(Win_Desktop, getter_AddRefs(localFile)); 
   1.699 +    }
   1.700 +    else if (inAtom == nsDirectoryService::sPrograms)
   1.701 +    {
   1.702 +        rv = GetSpecialSystemDirectory(Win_Programs, getter_AddRefs(localFile)); 
   1.703 +    }
   1.704 +    else if (inAtom == nsDirectoryService::sControls)
   1.705 +    {
   1.706 +        rv = GetSpecialSystemDirectory(Win_Controls, getter_AddRefs(localFile)); 
   1.707 +    }
   1.708 +    else if (inAtom == nsDirectoryService::sPrinters)
   1.709 +    {
   1.710 +        rv = GetSpecialSystemDirectory(Win_Printers, getter_AddRefs(localFile)); 
   1.711 +    }
   1.712 +    else if (inAtom == nsDirectoryService::sPersonal)
   1.713 +    {
   1.714 +        rv = GetSpecialSystemDirectory(Win_Personal, getter_AddRefs(localFile)); 
   1.715 +    }
   1.716 +    else if (inAtom == nsDirectoryService::sFavorites)
   1.717 +    {
   1.718 +        rv = GetSpecialSystemDirectory(Win_Favorites, getter_AddRefs(localFile)); 
   1.719 +    }
   1.720 +    else if (inAtom == nsDirectoryService::sStartup)
   1.721 +    {
   1.722 +        rv = GetSpecialSystemDirectory(Win_Startup, getter_AddRefs(localFile));
   1.723 +    }
   1.724 +    else if (inAtom == nsDirectoryService::sRecent)
   1.725 +    {
   1.726 +        rv = GetSpecialSystemDirectory(Win_Recent, getter_AddRefs(localFile)); 
   1.727 +    }
   1.728 +    else if (inAtom == nsDirectoryService::sSendto)
   1.729 +    {
   1.730 +        rv = GetSpecialSystemDirectory(Win_Sendto, getter_AddRefs(localFile)); 
   1.731 +    }
   1.732 +    else if (inAtom == nsDirectoryService::sBitbucket)
   1.733 +    {
   1.734 +        rv = GetSpecialSystemDirectory(Win_Bitbucket, getter_AddRefs(localFile)); 
   1.735 +    }
   1.736 +    else if (inAtom == nsDirectoryService::sStartmenu)
   1.737 +    {
   1.738 +        rv = GetSpecialSystemDirectory(Win_Startmenu, getter_AddRefs(localFile)); 
   1.739 +    }
   1.740 +    else if (inAtom == nsDirectoryService::sDesktopdirectory ||
   1.741 +             inAtom == nsDirectoryService::sOS_DesktopDirectory)
   1.742 +    {
   1.743 +        rv = GetSpecialSystemDirectory(Win_Desktopdirectory, getter_AddRefs(localFile)); 
   1.744 +    }
   1.745 +    else if (inAtom == nsDirectoryService::sDrives)
   1.746 +    {
   1.747 +        rv = GetSpecialSystemDirectory(Win_Drives, getter_AddRefs(localFile));
   1.748 +    }
   1.749 +    else if (inAtom == nsDirectoryService::sNetwork)
   1.750 +    {
   1.751 +        rv = GetSpecialSystemDirectory(Win_Network, getter_AddRefs(localFile)); 
   1.752 +    }
   1.753 +    else if (inAtom == nsDirectoryService::sNethood)
   1.754 +    {
   1.755 +        rv = GetSpecialSystemDirectory(Win_Nethood, getter_AddRefs(localFile)); 
   1.756 +    }
   1.757 +    else if (inAtom == nsDirectoryService::sFonts)
   1.758 +    {
   1.759 +        rv = GetSpecialSystemDirectory(Win_Fonts, getter_AddRefs(localFile));
   1.760 +    }
   1.761 +    else if (inAtom == nsDirectoryService::sTemplates)
   1.762 +    {
   1.763 +        rv = GetSpecialSystemDirectory(Win_Templates, getter_AddRefs(localFile)); 
   1.764 +    }
   1.765 +    else if (inAtom == nsDirectoryService::sCommon_Startmenu)
   1.766 +    {
   1.767 +        rv = GetSpecialSystemDirectory(Win_Common_Startmenu, getter_AddRefs(localFile)); 
   1.768 +    }
   1.769 +    else if (inAtom == nsDirectoryService::sCommon_Programs)
   1.770 +    {
   1.771 +        rv = GetSpecialSystemDirectory(Win_Common_Programs, getter_AddRefs(localFile)); 
   1.772 +    }
   1.773 +    else if (inAtom == nsDirectoryService::sCommon_Startup)
   1.774 +    {
   1.775 +        rv = GetSpecialSystemDirectory(Win_Common_Startup, getter_AddRefs(localFile)); 
   1.776 +    }
   1.777 +    else if (inAtom == nsDirectoryService::sCommon_Desktopdirectory)
   1.778 +    {
   1.779 +        rv = GetSpecialSystemDirectory(Win_Common_Desktopdirectory, getter_AddRefs(localFile)); 
   1.780 +    }
   1.781 +    else if (inAtom == nsDirectoryService::sCommon_AppData)
   1.782 +    {
   1.783 +        rv = GetSpecialSystemDirectory(Win_Common_AppData, getter_AddRefs(localFile)); 
   1.784 +    }
   1.785 +    else if (inAtom == nsDirectoryService::sAppdata)
   1.786 +    {
   1.787 +        rv = GetSpecialSystemDirectory(Win_Appdata, getter_AddRefs(localFile)); 
   1.788 +    }
   1.789 +    else if (inAtom == nsDirectoryService::sLocalAppdata)
   1.790 +    {
   1.791 +        rv = GetSpecialSystemDirectory(Win_LocalAppdata, getter_AddRefs(localFile)); 
   1.792 +    }
   1.793 +    else if (inAtom == nsDirectoryService::sPrinthood)
   1.794 +    {
   1.795 +        rv = GetSpecialSystemDirectory(Win_Printhood, getter_AddRefs(localFile)); 
   1.796 +    }
   1.797 +    else if (inAtom == nsDirectoryService::sWinCookiesDirectory)
   1.798 +    {
   1.799 +        rv = GetSpecialSystemDirectory(Win_Cookies, getter_AddRefs(localFile)); 
   1.800 +    }
   1.801 +    else if (inAtom == nsDirectoryService::sDefaultDownloadDirectory)
   1.802 +    {
   1.803 +        rv = GetSpecialSystemDirectory(Win_Downloads, getter_AddRefs(localFile));
   1.804 +    }
   1.805 +    else if (inAtom == nsDirectoryService::sDocs)
   1.806 +    {
   1.807 +        rv = GetSpecialSystemDirectory(Win_Documents, getter_AddRefs(localFile));
   1.808 +    }
   1.809 +    else if (inAtom == nsDirectoryService::sPictures)
   1.810 +    {
   1.811 +        rv = GetSpecialSystemDirectory(Win_Pictures, getter_AddRefs(localFile));
   1.812 +    }
   1.813 +    else if (inAtom == nsDirectoryService::sMusic)
   1.814 +    {
   1.815 +        rv = GetSpecialSystemDirectory(Win_Music, getter_AddRefs(localFile));
   1.816 +    }
   1.817 +    else if (inAtom == nsDirectoryService::sVideos)
   1.818 +    {
   1.819 +        rv = GetSpecialSystemDirectory(Win_Videos, getter_AddRefs(localFile));
   1.820 +    }
   1.821 +#elif defined (XP_UNIX)
   1.822 +
   1.823 +    else if (inAtom == nsDirectoryService::sLocalDirectory)
   1.824 +    {
   1.825 +        rv = GetSpecialSystemDirectory(Unix_LocalDirectory, getter_AddRefs(localFile)); 
   1.826 +    }
   1.827 +    else if (inAtom == nsDirectoryService::sLibDirectory)
   1.828 +    {
   1.829 +        rv = GetSpecialSystemDirectory(Unix_LibDirectory, getter_AddRefs(localFile));
   1.830 +    }
   1.831 +    else if (inAtom == nsDirectoryService::sOS_HomeDirectory)
   1.832 +    {
   1.833 +        rv = GetSpecialSystemDirectory(Unix_HomeDirectory, getter_AddRefs(localFile)); 
   1.834 +    }
   1.835 +    else if (inAtom == nsDirectoryService::sXDGDesktop ||
   1.836 +             inAtom == nsDirectoryService::sOS_DesktopDirectory)
   1.837 +    {
   1.838 +        rv = GetSpecialSystemDirectory(Unix_XDG_Desktop, getter_AddRefs(localFile));
   1.839 +        *persistent = false;
   1.840 +    }
   1.841 +    else if (inAtom == nsDirectoryService::sXDGDocuments)
   1.842 +    {
   1.843 +        rv = GetSpecialSystemDirectory(Unix_XDG_Documents, getter_AddRefs(localFile));
   1.844 +        *persistent = false;
   1.845 +    }
   1.846 +    else if (inAtom == nsDirectoryService::sXDGDownload ||
   1.847 +             inAtom == nsDirectoryService::sDefaultDownloadDirectory)
   1.848 +    {
   1.849 +        rv = GetSpecialSystemDirectory(Unix_XDG_Download, getter_AddRefs(localFile));
   1.850 +        *persistent = false;
   1.851 +    }
   1.852 +    else if (inAtom == nsDirectoryService::sXDGMusic)
   1.853 +    {
   1.854 +        rv = GetSpecialSystemDirectory(Unix_XDG_Music, getter_AddRefs(localFile));
   1.855 +        *persistent = false;
   1.856 +    }
   1.857 +    else if (inAtom == nsDirectoryService::sXDGPictures)
   1.858 +    {
   1.859 +        rv = GetSpecialSystemDirectory(Unix_XDG_Pictures, getter_AddRefs(localFile));
   1.860 +        *persistent = false;
   1.861 +    }
   1.862 +    else if (inAtom == nsDirectoryService::sXDGPublicShare)
   1.863 +    {
   1.864 +        rv = GetSpecialSystemDirectory(Unix_XDG_PublicShare, getter_AddRefs(localFile));
   1.865 +        *persistent = false;
   1.866 +    }
   1.867 +    else if (inAtom == nsDirectoryService::sXDGTemplates)
   1.868 +    {
   1.869 +        rv = GetSpecialSystemDirectory(Unix_XDG_Templates, getter_AddRefs(localFile));
   1.870 +        *persistent = false;
   1.871 +    }
   1.872 +    else if (inAtom == nsDirectoryService::sXDGVideos)
   1.873 +    {
   1.874 +        rv = GetSpecialSystemDirectory(Unix_XDG_Videos, getter_AddRefs(localFile));
   1.875 +        *persistent = false;
   1.876 +    }
   1.877 +#endif
   1.878 +
   1.879 +    if (NS_FAILED(rv))
   1.880 +        return rv;
   1.881 +
   1.882 +    if (!localFile)
   1.883 +        return NS_ERROR_FAILURE;
   1.884 +
   1.885 +    localFile.forget(_retval);
   1.886 +    return NS_OK;
   1.887 +}
   1.888 +
   1.889 +NS_IMETHODIMP
   1.890 +nsDirectoryService::GetFiles(const char *prop, nsISimpleEnumerator **_retval)
   1.891 +{
   1.892 +    if (NS_WARN_IF(!_retval))
   1.893 +        return NS_ERROR_INVALID_ARG;
   1.894 +    *_retval = nullptr;
   1.895 +        
   1.896 +    return NS_ERROR_FAILURE;
   1.897 +}

mercurial