Back to index

lightning-sunbird  0.9+nobinonly
nsDirectoryService.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   IBM Corp.
00024  *   Fredrik Holmqvist <thesuckiestemail@yahoo.se>
00025  *
00026  * Alternatively, the contents of this file may be used under the terms of
00027  * either of the GNU General Public License Version 2 or later (the "GPL"),
00028  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00029  * in which case the provisions of the GPL or the LGPL are applicable instead
00030  * of those above. If you wish to allow use of your version of this file only
00031  * under the terms of either the GPL or the LGPL, and not to allow others to
00032  * use your version of this file under the terms of the MPL, indicate your
00033  * decision by deleting the provisions above and replace them with the notice
00034  * and other provisions required by the GPL or the LGPL. If you do not delete
00035  * the provisions above, a recipient may use your version of this file under
00036  * the terms of any one of the MPL, the GPL or the LGPL.
00037  *
00038  * ***** END LICENSE BLOCK ***** */
00039 
00040 #include "nsCOMPtr.h"
00041 #include "nsAutoPtr.h"
00042 #include "nsDirectoryService.h"
00043 #include "nsDirectoryServiceDefs.h"
00044 #include "nsLocalFile.h"
00045 #include "nsDebug.h"
00046 #include "nsStaticAtom.h"
00047 #include "nsEnumeratorUtils.h"
00048 
00049 #include "nsICategoryManager.h"
00050 #include "nsISimpleEnumerator.h"
00051 #include "nsIStringEnumerator.h"
00052 
00053 #if defined(XP_MAC)
00054 #include <Folders.h>
00055 #include <Files.h>
00056 #include <Memory.h>
00057 #include <Processes.h>
00058 #include <Gestalt.h>
00059 #elif defined(XP_WIN)
00060 #include "nsWinAPIs.h"
00061 #include <windows.h>
00062 #include <shlobj.h>
00063 #include <stdlib.h>
00064 #include <stdio.h>
00065 #elif defined(XP_UNIX) || defined(XP_MACOSX)
00066 #include <unistd.h>
00067 #include <stdlib.h>
00068 #include <sys/param.h>
00069 #include "prenv.h"
00070 #ifdef XP_MACOSX
00071 #include <CoreServices/CoreServices.h>
00072 #include <Folders.h>
00073 #include <Files.h>
00074 #include <Memory.h>
00075 #include <Processes.h>
00076 #include <Gestalt.h>
00077 #include <CFURL.h>
00078 #include <InternetConfig.h>
00079 #endif
00080 #elif defined(XP_OS2)
00081 #define MAX_PATH _MAX_PATH
00082 #elif defined(XP_BEOS)
00083 #include <FindDirectory.h>
00084 #include <Path.h>
00085 #include <unistd.h>
00086 #include <stdlib.h>
00087 #include <sys/param.h>
00088 #include <OS.h>
00089 #include <image.h>
00090 #include "prenv.h"
00091 #endif
00092 
00093 #include "SpecialSystemDirectory.h"
00094 #include "nsAppFileLocationProvider.h"
00095 
00096 #if defined(XP_MAC)
00097 #define COMPONENT_REGISTRY_NAME NS_LITERAL_CSTRING("Component Registry")
00098 #define COMPONENT_DIRECTORY     NS_LITERAL_CSTRING("Components")
00099 #else
00100 #define COMPONENT_REGISTRY_NAME NS_LITERAL_CSTRING("compreg.dat")
00101 #define COMPONENT_DIRECTORY     NS_LITERAL_CSTRING("components")
00102 #endif 
00103 
00104 #define XPTI_REGISTRY_NAME      NS_LITERAL_CSTRING("xpti.dat")
00105 
00106 // define home directory
00107 // For Windows platform, We are choosing Appdata folder as HOME
00108 #if defined (XP_WIN)
00109 #define HOME_DIR NS_WIN_APPDATA_DIR
00110 #elif defined (XP_MAC) || defined (XP_MACOSX)
00111 #define HOME_DIR NS_OSX_HOME_DIR
00112 #elif defined (XP_UNIX)
00113 #define HOME_DIR NS_UNIX_HOME_DIR
00114 #elif defined (XP_OS2)
00115 #define HOME_DIR NS_OS2_HOME_DIR
00116 #elif defined (XP_BEOS)
00117 #define HOME_DIR NS_BEOS_HOME_DIR
00118 #endif
00119 
00120 //----------------------------------------------------------------------------------------
00121 nsresult 
00122 nsDirectoryService::GetCurrentProcessDirectory(nsILocalFile** aFile)
00123 //----------------------------------------------------------------------------------------
00124 {
00125     NS_ENSURE_ARG_POINTER(aFile);
00126     *aFile = nsnull;
00127     
00128    //  Set the component registry location:
00129     if (!gService)
00130         return NS_ERROR_FAILURE;
00131 
00132     nsresult rv; 
00133  
00134     nsCOMPtr<nsIProperties> dirService;
00135     rv = nsDirectoryService::Create(nsnull, 
00136                                     NS_GET_IID(nsIProperties), 
00137                                     getter_AddRefs(dirService));  // needs to be around for life of product
00138 
00139     if (dirService)
00140     {
00141       nsCOMPtr <nsILocalFile> aLocalFile;
00142       dirService->Get(NS_XPCOM_INIT_CURRENT_PROCESS_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(aLocalFile));
00143       if (aLocalFile)
00144       {
00145         *aFile = aLocalFile;
00146         NS_ADDREF(*aFile);
00147         return NS_OK;
00148       }
00149     }
00150 
00151     nsLocalFile* localFile = new nsLocalFile;
00152 
00153     if (localFile == nsnull)
00154         return NS_ERROR_OUT_OF_MEMORY;
00155     NS_ADDREF(localFile);
00156 
00157 
00158 
00159 #ifdef XP_WIN
00160     PRUnichar buf[MAX_PATH];
00161     if ( nsWinAPIs::mGetModuleFileName(0, buf, sizeof(buf)) )
00162     {
00163         // chop off the executable name by finding the rightmost backslash
00164         PRUnichar* lastSlash = wcsrchr(buf, L'\\');
00165         if (lastSlash)
00166             *(lastSlash + 1) = L'\0';
00167 
00168         localFile->InitWithPath(nsDependentString(buf));
00169         *aFile = localFile;
00170         return NS_OK;
00171     }
00172 
00173 #elif defined(XP_MAC)
00174     // get info for the the current process to determine the directory
00175     // its located in
00176     OSErr err;
00177     ProcessSerialNumber psn = {kNoProcess, kCurrentProcess};
00178     ProcessInfoRec pInfo;
00179     FSSpec         tempSpec;
00180 
00181     // initialize ProcessInfoRec before calling
00182     // GetProcessInformation() or die horribly.
00183     pInfo.processName = nil;
00184     pInfo.processAppSpec = &tempSpec;
00185     pInfo.processInfoLength = sizeof(ProcessInfoRec);
00186 
00187     err = GetProcessInformation(&psn, &pInfo);
00188     if (!err)
00189     {
00190         // create an FSSpec from the volume and dirid of the app.
00191         FSSpec appFSSpec;
00192         ::FSMakeFSSpec(pInfo.processAppSpec->vRefNum, pInfo.processAppSpec->parID, 0, &appFSSpec);
00193         
00194         nsCOMPtr<nsILocalFileMac> localFileMac = do_QueryInterface((nsIFile*)localFile);
00195         if (localFileMac) 
00196         {
00197             localFileMac->InitWithFSSpec(&appFSSpec);
00198             *aFile = localFile;
00199             return NS_OK;
00200         }
00201     }
00202 #elif defined(XP_MACOSX)
00203     // Works even if we're not bundled.
00204     CFBundleRef appBundle = CFBundleGetMainBundle();
00205     if (appBundle != nsnull)
00206     {
00207         CFURLRef bundleURL = CFBundleCopyExecutableURL(appBundle);
00208         if (bundleURL != nsnull)
00209         {
00210             CFURLRef parentURL = CFURLCreateCopyDeletingLastPathComponent(kCFAllocatorDefault, bundleURL);
00211             if (parentURL)
00212             {
00213                 // Pass PR_TRUE for the "resolveAgainstBase" arg to CFURLGetFileSystemRepresentation.
00214                 // This will resolve the relative portion of the CFURL against it base, giving a full
00215                 // path, which CFURLCopyFileSystemPath doesn't do.
00216                 char buffer[PATH_MAX];
00217                 if (CFURLGetFileSystemRepresentation(parentURL, PR_TRUE, (UInt8 *)buffer, sizeof(buffer)))
00218                 {
00219 #ifdef DEBUG_conrad
00220                     printf("nsDirectoryService - CurrentProcessDir is: %s\n", buffer);
00221 #endif
00222                     rv = localFile->InitWithNativePath(nsDependentCString(buffer));
00223                     if (NS_SUCCEEDED(rv))
00224                         *aFile = localFile;
00225                 }
00226                 CFRelease(parentURL);
00227             }
00228             CFRelease(bundleURL);
00229         }
00230     }
00231     
00232     NS_ASSERTION(*aFile, "nsDirectoryService - Could not determine CurrentProcessDir.\n");  
00233     if (*aFile)
00234         return NS_OK;
00235 
00236 #elif defined(XP_UNIX)
00237 
00238     // In the absence of a good way to get the executable directory let
00239     // us try this for unix:
00240     // - if MOZILLA_FIVE_HOME is defined, that is it
00241     // - else give the current directory
00242     char buf[MAXPATHLEN];
00243 
00244     // The MOZ_DEFAULT_MOZILLA_FIVE_HOME variable can be set at configure time with
00245     // a --with-default-mozilla-five-home=foo autoconf flag.
00246     // 
00247     // The idea here is to allow for builds that have a default MOZILLA_FIVE_HOME
00248     // regardless of the environment.  This makes it easier to write apps that
00249     // embed mozilla without having to worry about setting up the environment 
00250     //
00251     // We do this py putenv()ing the default value into the environment.  Note that
00252     // we only do this if it is not already set.
00253 #ifdef MOZ_DEFAULT_MOZILLA_FIVE_HOME
00254     if (PR_GetEnv("MOZILLA_FIVE_HOME") == nsnull)
00255     {
00256         putenv("MOZILLA_FIVE_HOME=" MOZ_DEFAULT_MOZILLA_FIVE_HOME);
00257     }
00258 #endif
00259 
00260     char *moz5 = PR_GetEnv("MOZILLA_FIVE_HOME");
00261 
00262     if (moz5)
00263     {
00264         if (realpath(moz5, buf)) {
00265             localFile->InitWithNativePath(nsDependentCString(buf));
00266             *aFile = localFile;
00267             return NS_OK;
00268         }
00269     }
00270 #if defined(DEBUG)
00271     static PRBool firstWarning = PR_TRUE;
00272 
00273     if(!moz5 && firstWarning) {
00274         // Warn that MOZILLA_FIVE_HOME not set, once.
00275         printf("Warning: MOZILLA_FIVE_HOME not set.\n");
00276         firstWarning = PR_FALSE;
00277     }
00278 #endif /* DEBUG */
00279 
00280     // Fall back to current directory.
00281     if (getcwd(buf, sizeof(buf)))
00282     {
00283         localFile->InitWithNativePath(nsDependentCString(buf));
00284         *aFile = localFile;
00285         return NS_OK;
00286     }
00287 
00288 #elif defined(XP_OS2)
00289     PPIB ppib;
00290     PTIB ptib;
00291     char buffer[CCHMAXPATH];
00292     DosGetInfoBlocks( &ptib, &ppib);
00293     DosQueryModuleName( ppib->pib_hmte, CCHMAXPATH, buffer);
00294     *strrchr( buffer, '\\') = '\0'; // XXX DBCS misery
00295     localFile->InitWithNativePath(nsDependentCString(buffer));
00296     *aFile = localFile;
00297     return NS_OK;
00298 
00299 #elif defined(XP_BEOS)
00300     char buf[MAXPATHLEN];
00301     int32 cookie = 0;
00302     image_info info;
00303     char *p;
00304     *buf = 0;
00305     if(get_next_image_info(0, &cookie, &info) == B_OK)
00306     {
00307         strcpy(buf, info.name);
00308         if((p = strrchr(buf, '/')) != 0)
00309         {
00310             if( (p-2 >= buf) && *(p-2)=='/' && *(p-1)=='.')
00311                 p -=2; 
00312             *p = 0;
00313             localFile->InitWithNativePath(nsDependentCString(buf));
00314             *aFile = localFile;
00315             return NS_OK;
00316         }
00317     }
00318 #endif
00319     
00320     NS_RELEASE(localFile);
00321 
00322     NS_ERROR("unable to get current process directory");
00323     return NS_ERROR_FAILURE;
00324 } // GetCurrentProcessDirectory()
00325 
00326 
00327 nsIAtom*  nsDirectoryService::sCurrentProcess = nsnull;
00328 nsIAtom*  nsDirectoryService::sComponentRegistry = nsnull;
00329 nsIAtom*  nsDirectoryService::sXPTIRegistry = nsnull;
00330 nsIAtom*  nsDirectoryService::sComponentDirectory = nsnull;
00331 nsIAtom*  nsDirectoryService::sGRE_Directory = nsnull;
00332 nsIAtom*  nsDirectoryService::sGRE_ComponentDirectory = nsnull;
00333 nsIAtom*  nsDirectoryService::sOS_DriveDirectory = nsnull;
00334 nsIAtom*  nsDirectoryService::sOS_TemporaryDirectory = nsnull;
00335 nsIAtom*  nsDirectoryService::sOS_CurrentProcessDirectory = nsnull;
00336 nsIAtom*  nsDirectoryService::sOS_CurrentWorkingDirectory = nsnull;
00337 nsIAtom*  nsDirectoryService::sOS_DesktopDirectory = nsnull;
00338 nsIAtom*  nsDirectoryService::sOS_HomeDirectory = nsnull;
00339 #if defined (XP_MACOSX)
00340 nsIAtom*  nsDirectoryService::sDirectory = nsnull;
00341 nsIAtom*  nsDirectoryService::sTrashDirectory = nsnull;
00342 nsIAtom*  nsDirectoryService::sStartupDirectory = nsnull;
00343 nsIAtom*  nsDirectoryService::sShutdownDirectory = nsnull;
00344 nsIAtom*  nsDirectoryService::sAppleMenuDirectory = nsnull;
00345 nsIAtom*  nsDirectoryService::sControlPanelDirectory = nsnull;
00346 nsIAtom*  nsDirectoryService::sExtensionDirectory = nsnull;
00347 nsIAtom*  nsDirectoryService::sFontsDirectory = nsnull;
00348 nsIAtom*  nsDirectoryService::sPreferencesDirectory = nsnull;
00349 nsIAtom*  nsDirectoryService::sDocumentsDirectory = nsnull;
00350 nsIAtom*  nsDirectoryService::sInternetSearchDirectory = nsnull;
00351 nsIAtom*  nsDirectoryService::sUserLibDirectory = nsnull;
00352 nsIAtom*  nsDirectoryService::sDefaultDownloadDirectory = nsnull;
00353 nsIAtom*  nsDirectoryService::sUserDesktopDirectory = nsnull;
00354 nsIAtom*  nsDirectoryService::sLocalDesktopDirectory = nsnull;
00355 nsIAtom*  nsDirectoryService::sUserApplicationsDirectory = nsnull;
00356 nsIAtom*  nsDirectoryService::sLocalApplicationsDirectory = nsnull;
00357 nsIAtom*  nsDirectoryService::sUserDocumentsDirectory = nsnull;
00358 nsIAtom*  nsDirectoryService::sLocalDocumentsDirectory = nsnull;
00359 nsIAtom*  nsDirectoryService::sUserInternetPlugInDirectory = nsnull;
00360 nsIAtom*  nsDirectoryService::sLocalInternetPlugInDirectory = nsnull;
00361 nsIAtom*  nsDirectoryService::sUserFrameworksDirectory = nsnull;
00362 nsIAtom*  nsDirectoryService::sLocalFrameworksDirectory = nsnull;
00363 nsIAtom*  nsDirectoryService::sUserPreferencesDirectory = nsnull;
00364 nsIAtom*  nsDirectoryService::sLocalPreferencesDirectory = nsnull;
00365 nsIAtom*  nsDirectoryService::sPictureDocumentsDirectory = nsnull;
00366 nsIAtom*  nsDirectoryService::sMovieDocumentsDirectory = nsnull;
00367 nsIAtom*  nsDirectoryService::sMusicDocumentsDirectory = nsnull;
00368 nsIAtom*  nsDirectoryService::sInternetSitesDirectory = nsnull;
00369 #elif defined (XP_WIN) 
00370 nsIAtom*  nsDirectoryService::sSystemDirectory = nsnull;
00371 nsIAtom*  nsDirectoryService::sWindowsDirectory = nsnull;
00372 nsIAtom*  nsDirectoryService::sWindowsProgramFiles = nsnull;
00373 nsIAtom*  nsDirectoryService::sDesktop = nsnull;
00374 nsIAtom*  nsDirectoryService::sPrograms = nsnull;
00375 nsIAtom*  nsDirectoryService::sControls = nsnull;
00376 nsIAtom*  nsDirectoryService::sPrinters = nsnull;
00377 nsIAtom*  nsDirectoryService::sPersonal = nsnull;
00378 nsIAtom*  nsDirectoryService::sFavorites = nsnull;
00379 nsIAtom*  nsDirectoryService::sStartup = nsnull;
00380 nsIAtom*  nsDirectoryService::sRecent = nsnull;
00381 nsIAtom*  nsDirectoryService::sSendto = nsnull;
00382 nsIAtom*  nsDirectoryService::sBitbucket = nsnull;
00383 nsIAtom*  nsDirectoryService::sStartmenu = nsnull;
00384 nsIAtom*  nsDirectoryService::sDesktopdirectory = nsnull;
00385 nsIAtom*  nsDirectoryService::sDrives = nsnull;
00386 nsIAtom*  nsDirectoryService::sNetwork = nsnull;
00387 nsIAtom*  nsDirectoryService::sNethood = nsnull;
00388 nsIAtom*  nsDirectoryService::sFonts = nsnull;
00389 nsIAtom*  nsDirectoryService::sTemplates = nsnull;
00390 nsIAtom*  nsDirectoryService::sCommon_Startmenu = nsnull;
00391 nsIAtom*  nsDirectoryService::sCommon_Programs = nsnull;
00392 nsIAtom*  nsDirectoryService::sCommon_Startup = nsnull;
00393 nsIAtom*  nsDirectoryService::sCommon_Desktopdirectory = nsnull;
00394 nsIAtom*  nsDirectoryService::sAppdata = nsnull;
00395 nsIAtom*  nsDirectoryService::sLocalAppdata = nsnull;
00396 nsIAtom*  nsDirectoryService::sPrinthood = nsnull;
00397 nsIAtom*  nsDirectoryService::sWinCookiesDirectory = nsnull;
00398 #elif defined (XP_UNIX)
00399 nsIAtom*  nsDirectoryService::sLocalDirectory = nsnull;
00400 nsIAtom*  nsDirectoryService::sLibDirectory = nsnull;
00401 #elif defined (XP_OS2)
00402 nsIAtom*  nsDirectoryService::sSystemDirectory = nsnull;
00403 nsIAtom*  nsDirectoryService::sOS2Directory = nsnull;
00404 #elif defined (XP_BEOS)
00405 nsIAtom*  nsDirectoryService::sSettingsDirectory = nsnull;
00406 nsIAtom*  nsDirectoryService::sSystemDirectory = nsnull;
00407 #endif
00408 
00409 
00410 nsDirectoryService* nsDirectoryService::gService = nsnull;
00411 
00412 nsDirectoryService::nsDirectoryService() :
00413     mHashtable(256, PR_TRUE)
00414 {
00415 }
00416 
00417 NS_METHOD
00418 nsDirectoryService::Create(nsISupports *outer, REFNSIID aIID, void **aResult)
00419 {
00420     NS_ENSURE_ARG_POINTER(aResult);
00421     NS_ENSURE_NO_AGGREGATION(outer);
00422 
00423     if (!gService)
00424     {
00425         return NS_ERROR_NOT_INITIALIZED;
00426     }
00427 
00428     return gService->QueryInterface(aIID, aResult);
00429 }
00430 
00431 static const nsStaticAtom directory_atoms[] = {
00432     { NS_XPCOM_CURRENT_PROCESS_DIR,     &nsDirectoryService::sCurrentProcess },
00433     { NS_XPCOM_COMPONENT_REGISTRY_FILE, &nsDirectoryService::sComponentRegistry },
00434     { NS_XPCOM_COMPONENT_DIR,         &nsDirectoryService::sComponentDirectory },
00435     { NS_XPCOM_XPTI_REGISTRY_FILE, &nsDirectoryService::sXPTIRegistry },
00436     { NS_GRE_DIR,                  &nsDirectoryService::sGRE_Directory },
00437     { NS_GRE_COMPONENT_DIR,        &nsDirectoryService::sGRE_ComponentDirectory },
00438     { NS_OS_DRIVE_DIR,             &nsDirectoryService::sOS_DriveDirectory },
00439     { NS_OS_TEMP_DIR,              &nsDirectoryService::sOS_TemporaryDirectory },
00440     { NS_OS_CURRENT_PROCESS_DIR,   &nsDirectoryService::sOS_CurrentProcessDirectory },
00441     { NS_OS_CURRENT_WORKING_DIR,   &nsDirectoryService::sOS_CurrentWorkingDirectory },
00442     { NS_OS_HOME_DIR,              &nsDirectoryService::sOS_HomeDirectory },
00443     { NS_OS_DESKTOP_DIR,           &nsDirectoryService::sOS_DesktopDirectory },
00444     { NS_XPCOM_INIT_CURRENT_PROCESS_DIR, nsnull },
00445 #if defined (XP_MACOSX)
00446     { NS_OS_SYSTEM_DIR,                   &nsDirectoryService::sDirectory },
00447     { NS_MAC_TRASH_DIR,                   &nsDirectoryService::sTrashDirectory },
00448     { NS_MAC_STARTUP_DIR,                 &nsDirectoryService::sStartupDirectory },
00449     { NS_MAC_SHUTDOWN_DIR,                &nsDirectoryService::sShutdownDirectory },
00450     { NS_MAC_APPLE_MENU_DIR,              &nsDirectoryService::sAppleMenuDirectory },
00451     { NS_MAC_CONTROL_PANELS_DIR,          &nsDirectoryService::sControlPanelDirectory },
00452     { NS_MAC_EXTENSIONS_DIR,              &nsDirectoryService::sExtensionDirectory },
00453     { NS_MAC_FONTS_DIR,                   &nsDirectoryService::sFontsDirectory },
00454     { NS_MAC_PREFS_DIR,                   &nsDirectoryService::sPreferencesDirectory },
00455     { NS_MAC_DOCUMENTS_DIR,               &nsDirectoryService::sDocumentsDirectory },
00456     { NS_MAC_INTERNET_SEARCH_DIR,         &nsDirectoryService::sInternetSearchDirectory },
00457     { NS_MAC_USER_LIB_DIR,                &nsDirectoryService::sUserLibDirectory },
00458     { NS_OSX_DEFAULT_DOWNLOAD_DIR,        &nsDirectoryService::sDefaultDownloadDirectory },
00459     { NS_OSX_USER_DESKTOP_DIR,            &nsDirectoryService::sUserDesktopDirectory },
00460     { NS_OSX_LOCAL_DESKTOP_DIR,           &nsDirectoryService::sLocalDesktopDirectory },
00461     { NS_OSX_USER_APPLICATIONS_DIR,       &nsDirectoryService::sUserApplicationsDirectory },
00462     { NS_OSX_LOCAL_APPLICATIONS_DIR,      &nsDirectoryService::sLocalApplicationsDirectory },
00463     { NS_OSX_USER_DOCUMENTS_DIR,          &nsDirectoryService::sUserDocumentsDirectory },
00464     { NS_OSX_LOCAL_DOCUMENTS_DIR,         &nsDirectoryService::sLocalDocumentsDirectory },
00465     { NS_OSX_USER_INTERNET_PLUGIN_DIR,    &nsDirectoryService::sUserInternetPlugInDirectory },
00466     { NS_OSX_LOCAL_INTERNET_PLUGIN_DIR,   &nsDirectoryService::sLocalInternetPlugInDirectory },
00467     { NS_OSX_USER_FRAMEWORKS_DIR,         &nsDirectoryService::sUserFrameworksDirectory },
00468     { NS_OSX_LOCAL_FRAMEWORKS_DIR,        &nsDirectoryService::sLocalFrameworksDirectory },
00469     { NS_OSX_USER_PREFERENCES_DIR,        &nsDirectoryService::sUserPreferencesDirectory },
00470     { NS_OSX_LOCAL_PREFERENCES_DIR,       &nsDirectoryService::sLocalPreferencesDirectory },
00471     { NS_OSX_PICTURE_DOCUMENTS_DIR,       &nsDirectoryService::sPictureDocumentsDirectory },
00472     { NS_OSX_MOVIE_DOCUMENTS_DIR,         &nsDirectoryService::sMovieDocumentsDirectory },
00473     { NS_OSX_MUSIC_DOCUMENTS_DIR,         &nsDirectoryService::sMusicDocumentsDirectory },
00474     { NS_OSX_INTERNET_SITES_DIR,          &nsDirectoryService::sInternetSitesDirectory },
00475 #elif defined (XP_WIN) 
00476     { NS_OS_SYSTEM_DIR,            &nsDirectoryService::sSystemDirectory },
00477     { NS_WIN_WINDOWS_DIR,          &nsDirectoryService::sWindowsDirectory },
00478     { NS_WIN_PROGRAM_FILES_DIR,    &nsDirectoryService::sWindowsProgramFiles },
00479     { NS_WIN_DESKTOP_DIR,          &nsDirectoryService::sDesktop },
00480     { NS_WIN_PROGRAMS_DIR,         &nsDirectoryService::sPrograms },
00481     { NS_WIN_CONTROLS_DIR,         &nsDirectoryService::sControls },
00482     { NS_WIN_PRINTERS_DIR,         &nsDirectoryService::sPrinters },
00483     { NS_WIN_PERSONAL_DIR,         &nsDirectoryService::sPersonal },
00484     { NS_WIN_FAVORITES_DIR,        &nsDirectoryService::sFavorites },
00485     { NS_WIN_STARTUP_DIR,          &nsDirectoryService::sStartup },
00486     { NS_WIN_RECENT_DIR,           &nsDirectoryService::sRecent },
00487     { NS_WIN_SEND_TO_DIR,          &nsDirectoryService::sSendto },
00488     { NS_WIN_BITBUCKET_DIR,        &nsDirectoryService::sBitbucket },
00489     { NS_WIN_STARTMENU_DIR,        &nsDirectoryService::sStartmenu },
00490     { NS_WIN_DESKTOP_DIRECTORY,    &nsDirectoryService::sDesktopdirectory },
00491     { NS_WIN_DRIVES_DIR,           &nsDirectoryService::sDrives },
00492     { NS_WIN_NETWORK_DIR,          &nsDirectoryService::sNetwork },
00493     { NS_WIN_NETHOOD_DIR,          &nsDirectoryService::sNethood },
00494     { NS_WIN_FONTS_DIR,            &nsDirectoryService::sFonts },
00495     { NS_WIN_TEMPLATES_DIR,        &nsDirectoryService::sTemplates },
00496     { NS_WIN_COMMON_STARTMENU_DIR, &nsDirectoryService::sCommon_Startmenu },
00497     { NS_WIN_COMMON_PROGRAMS_DIR,  &nsDirectoryService::sCommon_Programs },
00498     { NS_WIN_COMMON_STARTUP_DIR,   &nsDirectoryService::sCommon_Startup },
00499     { NS_WIN_COMMON_DESKTOP_DIRECTORY, &nsDirectoryService::sCommon_Desktopdirectory },
00500     { NS_WIN_APPDATA_DIR,          &nsDirectoryService::sAppdata },
00501     { NS_WIN_LOCAL_APPDATA_DIR,    &nsDirectoryService::sLocalAppdata },
00502     { NS_WIN_PRINTHOOD,            &nsDirectoryService::sPrinthood },
00503     { NS_WIN_COOKIES_DIR,          &nsDirectoryService::sWinCookiesDirectory },
00504 #elif defined (XP_UNIX)
00505     { NS_UNIX_LOCAL_DIR,           &nsDirectoryService::sLocalDirectory },
00506     { NS_UNIX_LIB_DIR,             &nsDirectoryService::sLibDirectory },
00507 #elif defined (XP_OS2)
00508     { NS_OS_SYSTEM_DIR,            &nsDirectoryService::sSystemDirectory },
00509     { NS_OS2_DIR,                  &nsDirectoryService::sOS2Directory },
00510 #elif defined (XP_BEOS)
00511     { NS_OS_SYSTEM_DIR,            &nsDirectoryService::sSystemDirectory },
00512     { NS_BEOS_SETTINGS_DIR,        &nsDirectoryService::sSettingsDirectory },
00513 #endif
00514 };    
00515 
00516 NS_IMETHODIMP
00517 nsDirectoryService::Init()
00518 {
00519     NS_NOTREACHED("Don't call me, I was for internal use only!");
00520     return NS_OK;
00521 }
00522 
00523 nsresult
00524 nsDirectoryService::RealInit()
00525 {
00526     NS_ASSERTION(!gService, "Mustn't initialize twice!");
00527 
00528     nsresult rv;
00529 
00530     nsRefPtr<nsDirectoryService> self = new nsDirectoryService();
00531     if (!self)
00532         return NS_ERROR_OUT_OF_MEMORY;
00533 
00534     rv = NS_NewISupportsArray(getter_AddRefs(((nsDirectoryService*) self)->mProviders));
00535     if (NS_FAILED(rv))
00536         return rv;
00537 
00538     NS_RegisterStaticAtoms(directory_atoms, NS_ARRAY_LENGTH(directory_atoms));
00539     
00540     // Let the list hold the only reference to the provider.
00541     nsAppFileLocationProvider *defaultProvider = new nsAppFileLocationProvider;
00542     if (!defaultProvider)
00543         return NS_ERROR_OUT_OF_MEMORY;
00544     // AppendElement returns PR_TRUE for success.
00545     rv = ((nsDirectoryService*) self)->mProviders->AppendElement(defaultProvider) ? NS_OK : NS_ERROR_FAILURE;
00546     if (NS_FAILED(rv))
00547         return rv;
00548 
00549     self.swap(gService);
00550     return NS_OK;
00551 }
00552 
00553 PRBool
00554 nsDirectoryService::ReleaseValues(nsHashKey* key, void* data, void* closure)
00555 {
00556     nsISupports* value = (nsISupports*)data;
00557     NS_IF_RELEASE(value);
00558     return PR_TRUE;
00559 }
00560 
00561 nsDirectoryService::~nsDirectoryService()
00562 {
00563 }
00564 
00565 NS_IMPL_THREADSAFE_ISUPPORTS4(nsDirectoryService, nsIProperties, nsIDirectoryService, nsIDirectoryServiceProvider, nsIDirectoryServiceProvider2)
00566 
00567 
00568 NS_IMETHODIMP
00569 nsDirectoryService::Undefine(const char* prop)
00570 {
00571     nsCStringKey key(prop);
00572     if (!mHashtable.Exists(&key))
00573         return NS_ERROR_FAILURE;
00574 
00575     mHashtable.Remove (&key);
00576     return NS_OK;
00577  }
00578 
00579 NS_IMETHODIMP
00580 nsDirectoryService::GetKeys(PRUint32 *count, char ***keys)
00581 {
00582     return NS_ERROR_NOT_IMPLEMENTED;
00583 }
00584 
00585 struct FileData
00586 {
00587   FileData(const char* aProperty,
00588            const nsIID& aUUID) :
00589     property(aProperty),
00590     data(nsnull),
00591     persistent(PR_TRUE),
00592     uuid(aUUID) {}
00593     
00594   const char*   property;
00595   nsISupports*  data;
00596   PRBool        persistent;
00597   const nsIID&  uuid;
00598 };
00599 
00600 static PRBool FindProviderFile(nsISupports* aElement, void *aData)
00601 {
00602   nsresult rv;
00603   FileData* fileData = (FileData*)aData;
00604   if (fileData->uuid.Equals(NS_GET_IID(nsISimpleEnumerator)))
00605   {
00606       // Not all providers implement this iface
00607       nsCOMPtr<nsIDirectoryServiceProvider2> prov2 = do_QueryInterface(aElement);
00608       if (prov2)
00609       {
00610           nsCOMPtr<nsISimpleEnumerator> newFiles;
00611           rv = prov2->GetFiles(fileData->property, getter_AddRefs(newFiles));
00612           if (NS_SUCCEEDED(rv) && newFiles) {
00613               if (fileData->data) {
00614                   nsCOMPtr<nsISimpleEnumerator> unionFiles;
00615 
00616                   NS_NewUnionEnumerator(getter_AddRefs(unionFiles),
00617                                         (nsISimpleEnumerator*) fileData->data, newFiles);
00618 
00619                   if (unionFiles)
00620                       unionFiles.swap(* (nsISimpleEnumerator**) &fileData->data);
00621               }
00622               else
00623               {
00624                   NS_ADDREF(fileData->data = newFiles);
00625               }
00626                   
00627               fileData->persistent = PR_FALSE; // Enumerators can never be persistent
00628               return rv == NS_SUCCESS_AGGREGATE_RESULT;
00629           }
00630       }
00631   }
00632   else
00633   {
00634       nsCOMPtr<nsIDirectoryServiceProvider> prov = do_QueryInterface(aElement);
00635       if (prov)
00636       {
00637           rv = prov->GetFile(fileData->property, &fileData->persistent, (nsIFile **)&fileData->data);
00638           if (NS_SUCCEEDED(rv) && fileData->data)
00639               return PR_FALSE;
00640       }
00641   }
00642 
00643   return PR_TRUE;
00644 }
00645 
00646 NS_IMETHODIMP
00647 nsDirectoryService::Get(const char* prop, const nsIID & uuid, void* *result)
00648 {
00649     nsCStringKey key(prop);
00650     
00651     nsCOMPtr<nsISupports> value = dont_AddRef(mHashtable.Get(&key));
00652     
00653     if (value)
00654     {
00655         nsCOMPtr<nsIFile> cloneFile;
00656         nsCOMPtr<nsIFile> cachedFile = do_QueryInterface(value);
00657         NS_ASSERTION(cachedFile, "nsIFile expected");
00658 
00659         cachedFile->Clone(getter_AddRefs(cloneFile));
00660         return cloneFile->QueryInterface(uuid, result);
00661     }
00662 
00663     // it is not one of our defaults, lets check any providers
00664     FileData fileData(prop, uuid);
00665 
00666     mProviders->EnumerateBackwards(FindProviderFile, &fileData);
00667     if (fileData.data)
00668     {
00669         if (fileData.persistent)
00670         {
00671             Set(prop, NS_STATIC_CAST(nsIFile*, fileData.data));
00672         }
00673         nsresult rv = (fileData.data)->QueryInterface(uuid, result);
00674         NS_RELEASE(fileData.data);  // addref occurs in FindProviderFile()
00675         return rv;
00676     }
00677 
00678     FindProviderFile(NS_STATIC_CAST(nsIDirectoryServiceProvider*, this), &fileData);
00679     if (fileData.data)
00680     {
00681         if (fileData.persistent)
00682         {
00683             Set(prop, NS_STATIC_CAST(nsIFile*, fileData.data));
00684         }
00685         nsresult rv = (fileData.data)->QueryInterface(uuid, result);
00686         NS_RELEASE(fileData.data);  // addref occurs in FindProviderFile()
00687         return rv;
00688     }
00689 
00690     return NS_ERROR_FAILURE;
00691 }
00692 
00693 NS_IMETHODIMP
00694 nsDirectoryService::Set(const char* prop, nsISupports* value)
00695 {
00696     nsCStringKey key(prop);
00697     if (mHashtable.Exists(&key) || value == nsnull)
00698         return NS_ERROR_FAILURE;
00699 
00700     nsCOMPtr<nsIFile> ourFile;
00701     value->QueryInterface(NS_GET_IID(nsIFile), getter_AddRefs(ourFile));
00702     if (ourFile)
00703     {
00704       nsCOMPtr<nsIFile> cloneFile;
00705       ourFile->Clone (getter_AddRefs (cloneFile));
00706       mHashtable.Put(&key, cloneFile);
00707 
00708       return NS_OK;
00709     }
00710 
00711     return NS_ERROR_FAILURE;   
00712 }
00713 
00714 NS_IMETHODIMP
00715 nsDirectoryService::Has(const char *prop, PRBool *_retval)
00716 {
00717     *_retval = PR_FALSE;
00718     nsCOMPtr<nsIFile> value;
00719     nsresult rv = Get(prop, NS_GET_IID(nsIFile), getter_AddRefs(value));
00720     if (NS_FAILED(rv))
00721         return NS_OK;
00722     
00723     if (value)
00724     {
00725         *_retval = PR_TRUE;
00726     }
00727     
00728     return rv;
00729 }
00730 
00731 NS_IMETHODIMP
00732 nsDirectoryService::RegisterProvider(nsIDirectoryServiceProvider *prov)
00733 {
00734     nsresult rv;
00735     if (!prov)
00736         return NS_ERROR_FAILURE;
00737     if (!mProviders)
00738         return NS_ERROR_NOT_INITIALIZED;
00739 
00740     nsCOMPtr<nsISupports> supports = do_QueryInterface(prov, &rv);
00741     if (NS_FAILED(rv)) return rv;
00742 
00743     // AppendElement returns PR_TRUE for success.
00744     return mProviders->AppendElement(supports) ? NS_OK : NS_ERROR_FAILURE;
00745 }
00746 
00747 void
00748 nsDirectoryService::RegisterCategoryProviders()
00749 {
00750     nsCOMPtr<nsICategoryManager> catman
00751         (do_GetService(NS_CATEGORYMANAGER_CONTRACTID));
00752     if (!catman)
00753         return;
00754 
00755     nsCOMPtr<nsISimpleEnumerator> entries;
00756     catman->EnumerateCategory(XPCOM_DIRECTORY_PROVIDER_CATEGORY,
00757                               getter_AddRefs(entries));
00758 
00759     nsCOMPtr<nsIUTF8StringEnumerator> strings(do_QueryInterface(entries));
00760     if (!strings)
00761         return;
00762 
00763     PRBool more;
00764     while (NS_SUCCEEDED(strings->HasMore(&more)) && more) {
00765         nsCAutoString entry;
00766         strings->GetNext(entry);
00767 
00768         nsXPIDLCString contractID;
00769         catman->GetCategoryEntry(XPCOM_DIRECTORY_PROVIDER_CATEGORY, entry.get(), getter_Copies(contractID));
00770 
00771         if (contractID) {
00772             nsCOMPtr<nsIDirectoryServiceProvider> provider = do_GetService(contractID.get());
00773             if (provider)
00774                 RegisterProvider(provider);
00775         }
00776     }
00777 }
00778 
00779 NS_IMETHODIMP
00780 nsDirectoryService::UnregisterProvider(nsIDirectoryServiceProvider *prov)
00781 {
00782     nsresult rv;
00783     if (!prov)
00784         return NS_ERROR_FAILURE;
00785     if (!mProviders)
00786         return NS_ERROR_NOT_INITIALIZED;
00787 
00788     nsCOMPtr<nsISupports> supports = do_QueryInterface(prov, &rv);
00789     if (NS_FAILED(rv)) return rv;
00790 
00791     // RemoveElement returns PR_TRUE for success.
00792     return mProviders->RemoveElement(supports) ? NS_OK : NS_ERROR_FAILURE;
00793 }
00794 
00795 // DO NOT ADD ANY LOCATIONS TO THIS FUNCTION UNTIL YOU TALK TO: dougt@netscape.com.
00796 // This is meant to be a place of xpcom or system specific file locations, not
00797 // application specific locations.  If you need the later, register a callback for
00798 // your application.  
00799 
00800 NS_IMETHODIMP
00801 nsDirectoryService::GetFile(const char *prop, PRBool *persistent, nsIFile **_retval)
00802 {
00803        nsCOMPtr<nsILocalFile> localFile;
00804        nsresult rv = NS_ERROR_FAILURE;
00805 
00806        *_retval = nsnull;
00807        *persistent = PR_TRUE;
00808 
00809     nsIAtom* inAtom = NS_NewAtom(prop);
00810 
00811        // check to see if it is one of our defaults
00812         
00813     if (inAtom == nsDirectoryService::sCurrentProcess || 
00814         inAtom == nsDirectoryService::sOS_CurrentProcessDirectory )
00815     {
00816         rv = GetCurrentProcessDirectory(getter_AddRefs(localFile));
00817     }
00818     else if (inAtom == nsDirectoryService::sComponentRegistry)
00819     {
00820         rv = GetCurrentProcessDirectory(getter_AddRefs(localFile));
00821         if (!localFile)
00822             return NS_ERROR_FAILURE;
00823 
00824         localFile->AppendNative(COMPONENT_DIRECTORY);           
00825         localFile->AppendNative(COMPONENT_REGISTRY_NAME);           
00826     }
00827     else if (inAtom == nsDirectoryService::sXPTIRegistry)
00828     {
00829         rv = GetCurrentProcessDirectory(getter_AddRefs(localFile));
00830         if (!localFile)
00831             return NS_ERROR_FAILURE;
00832 
00833         localFile->AppendNative(COMPONENT_DIRECTORY);           
00834         localFile->AppendNative(XPTI_REGISTRY_NAME);           
00835     }
00836     
00837     // Unless otherwise set, the core pieces of the GRE exist
00838     // in the current process directory.
00839     else if (inAtom == nsDirectoryService::sGRE_Directory)
00840     {
00841         rv = GetCurrentProcessDirectory(getter_AddRefs(localFile));
00842     }
00843     // the GRE components directory is relative to the GRE directory
00844     // by default; applications may override this behavior in special
00845     // cases
00846     else if (inAtom == nsDirectoryService::sGRE_ComponentDirectory)
00847     {
00848         rv = Get(NS_GRE_DIR, nsILocalFile::GetIID(), getter_AddRefs(localFile));
00849         if (localFile)
00850              localFile->AppendNative(COMPONENT_DIRECTORY);
00851     }
00852     else if (inAtom == nsDirectoryService::sComponentDirectory)
00853     {
00854         rv = GetCurrentProcessDirectory(getter_AddRefs(localFile));
00855         if (localFile)
00856                   localFile->AppendNative(COMPONENT_DIRECTORY);           
00857     }
00858     else if (inAtom == nsDirectoryService::sOS_DriveDirectory)
00859     {
00860         rv = GetSpecialSystemDirectory(OS_DriveDirectory, getter_AddRefs(localFile));
00861     }
00862     else if (inAtom == nsDirectoryService::sOS_TemporaryDirectory)
00863     {
00864         rv = GetSpecialSystemDirectory(OS_TemporaryDirectory, getter_AddRefs(localFile));
00865     }
00866     else if (inAtom == nsDirectoryService::sOS_CurrentProcessDirectory)
00867     {
00868         rv = GetSpecialSystemDirectory(OS_CurrentProcessDirectory, getter_AddRefs(localFile)); 
00869     }
00870     else if (inAtom == nsDirectoryService::sOS_CurrentWorkingDirectory)
00871     {
00872         rv = GetSpecialSystemDirectory(OS_CurrentWorkingDirectory, getter_AddRefs(localFile)); 
00873     }
00874        
00875 #if defined(XP_MACOSX)
00876     else if (inAtom == nsDirectoryService::sDirectory)
00877     {
00878         rv = GetOSXFolderType(kClassicDomain, kSystemFolderType, getter_AddRefs(localFile));
00879     }
00880     else if (inAtom == nsDirectoryService::sTrashDirectory)
00881     {
00882         rv = GetOSXFolderType(kClassicDomain, kTrashFolderType, getter_AddRefs(localFile));
00883     }
00884     else if (inAtom == nsDirectoryService::sStartupDirectory)
00885     {
00886         rv = GetOSXFolderType(kClassicDomain, kStartupFolderType, getter_AddRefs(localFile));
00887     }
00888     else if (inAtom == nsDirectoryService::sShutdownDirectory)
00889     {
00890         rv = GetOSXFolderType(kClassicDomain, kShutdownFolderType, getter_AddRefs(localFile));
00891     }
00892     else if (inAtom == nsDirectoryService::sAppleMenuDirectory)
00893     {
00894         rv = GetOSXFolderType(kClassicDomain, kAppleMenuFolderType, getter_AddRefs(localFile));
00895     }
00896     else if (inAtom == nsDirectoryService::sControlPanelDirectory)
00897     {
00898         rv = GetOSXFolderType(kClassicDomain, kControlPanelFolderType, getter_AddRefs(localFile));
00899     }
00900     else if (inAtom == nsDirectoryService::sExtensionDirectory)
00901     {
00902         rv = GetOSXFolderType(kClassicDomain, kExtensionFolderType, getter_AddRefs(localFile));
00903     }
00904     else if (inAtom == nsDirectoryService::sFontsDirectory)
00905     {
00906         rv = GetOSXFolderType(kClassicDomain, kFontsFolderType, getter_AddRefs(localFile));
00907     }
00908     else if (inAtom == nsDirectoryService::sPreferencesDirectory)
00909     {
00910         rv = GetOSXFolderType(kClassicDomain, kPreferencesFolderType, getter_AddRefs(localFile));
00911     }
00912     else if (inAtom == nsDirectoryService::sDocumentsDirectory)
00913     {
00914         rv = GetOSXFolderType(kClassicDomain, kDocumentsFolderType, getter_AddRefs(localFile));
00915     }
00916     else if (inAtom == nsDirectoryService::sInternetSearchDirectory)
00917     {
00918         rv = GetOSXFolderType(kClassicDomain, kInternetSearchSitesFolderType, getter_AddRefs(localFile));
00919     }   
00920     else if (inAtom == nsDirectoryService::sUserLibDirectory)
00921     {
00922         rv = GetOSXFolderType(kUserDomain, kDomainLibraryFolderType, getter_AddRefs(localFile));
00923     }
00924     else if (inAtom == nsDirectoryService::sOS_HomeDirectory)
00925     {
00926         rv = GetOSXFolderType(kUserDomain, kDomainTopLevelFolderType, getter_AddRefs(localFile));
00927     }
00928     else if (inAtom == nsDirectoryService::sDefaultDownloadDirectory)
00929     {
00930         NS_NewLocalFile(EmptyString(), PR_TRUE, getter_AddRefs(localFile));
00931         nsCOMPtr<nsILocalFileMac> localMacFile(do_QueryInterface(localFile));
00932 
00933         if (localMacFile)
00934         {
00935             OSErr err;
00936             ICInstance icInstance;
00937 
00938             err = ::ICStart(&icInstance, 'XPCM');
00939             if (err == noErr)
00940             {
00941                 // ICGetPref() crashes when getting the download directory if the download
00942                 // directory has never been specified (e.g. a new user account), bug 265903.
00943                 // To work around this we enumerate through the IC prefs to see if the
00944                 // download directory has been specified before trying to obtain it.
00945                 long numPrefs = 0;
00946                 err = ::ICCountPref(icInstance, &numPrefs);
00947                 if (err == noErr)
00948                 {
00949                     for ( long i = 0; i < numPrefs; ++i )
00950                     {
00951                         Str255 key;
00952                         err = ::ICGetIndPref(icInstance, i, key);
00953                         if ( err == noErr && ( PLstrcmp( key, kICDownloadFolder ) == 0 ) )
00954                         {
00955                             ICAttr attrs;
00956                             ICFileSpec icFileSpec;
00957                           long size = kICFileSpecHeaderSize;
00958                             err = ::ICGetPref(icInstance, kICDownloadFolder, &attrs, &icFileSpec, &size);
00959                             if (err == noErr || (err == icTruncatedErr && size >= kICFileSpecHeaderSize))
00960                             {
00961                                 rv = localMacFile->InitWithFSSpec(&icFileSpec.fss);
00962                             }
00963                             break;
00964                         }
00965                     }
00966                 }
00967                 ::ICStop(icInstance);
00968             }
00969             
00970             if NS_FAILED(rv)
00971             { 
00972                 // We got an error getting the DL folder from IC so try finding the user's Desktop folder
00973                 rv = GetOSXFolderType(kUserDomain, kDesktopFolderType, getter_AddRefs(localFile));
00974             }
00975         }
00976         
00977         // Don't cache the DL directory as the user may change it while we're running.
00978         // Negligible perf hit as this directory is only requested for downloads
00979         *persistent = PR_FALSE;
00980     }
00981     else if (inAtom == nsDirectoryService::sUserDesktopDirectory ||
00982              inAtom == nsDirectoryService::sOS_DesktopDirectory)
00983     {
00984         rv = GetOSXFolderType(kUserDomain, kDesktopFolderType, getter_AddRefs(localFile));
00985     }
00986     else if (inAtom == nsDirectoryService::sLocalDesktopDirectory)
00987     {
00988         rv = GetOSXFolderType(kLocalDomain, kDesktopFolderType, getter_AddRefs(localFile));
00989     }
00990     else if (inAtom == nsDirectoryService::sUserApplicationsDirectory)
00991     {
00992         rv = GetOSXFolderType(kUserDomain, kApplicationsFolderType, getter_AddRefs(localFile));
00993     }
00994     else if (inAtom == nsDirectoryService::sLocalApplicationsDirectory)
00995     {
00996         rv = GetOSXFolderType(kLocalDomain, kApplicationsFolderType, getter_AddRefs(localFile));
00997     }
00998     else if (inAtom == nsDirectoryService::sUserDocumentsDirectory)
00999     {
01000         rv = GetOSXFolderType(kUserDomain, kDocumentsFolderType, getter_AddRefs(localFile));
01001     }
01002     else if (inAtom == nsDirectoryService::sLocalDocumentsDirectory)
01003     {
01004         rv = GetOSXFolderType(kLocalDomain, kDocumentsFolderType, getter_AddRefs(localFile));
01005     }
01006     else if (inAtom == nsDirectoryService::sUserInternetPlugInDirectory)
01007     {
01008         rv = GetOSXFolderType(kUserDomain, kInternetPlugInFolderType, getter_AddRefs(localFile));
01009     }
01010     else if (inAtom == nsDirectoryService::sLocalInternetPlugInDirectory)
01011     {
01012         rv = GetOSXFolderType(kLocalDomain, kInternetPlugInFolderType, getter_AddRefs(localFile));
01013     }
01014     else if (inAtom == nsDirectoryService::sUserFrameworksDirectory)
01015     {
01016         rv = GetOSXFolderType(kUserDomain, kFrameworksFolderType, getter_AddRefs(localFile));
01017     }
01018     else if (inAtom == nsDirectoryService::sLocalFrameworksDirectory)
01019     {
01020         rv = GetOSXFolderType(kLocalDomain, kFrameworksFolderType, getter_AddRefs(localFile));
01021     }
01022     else if (inAtom == nsDirectoryService::sUserPreferencesDirectory)
01023     {
01024         rv = GetOSXFolderType(kUserDomain, kPreferencesFolderType, getter_AddRefs(localFile));
01025     }
01026     else if (inAtom == nsDirectoryService::sLocalPreferencesDirectory)
01027     {
01028         rv = GetOSXFolderType(kLocalDomain, kPreferencesFolderType, getter_AddRefs(localFile));
01029     }
01030     else if (inAtom == nsDirectoryService::sPictureDocumentsDirectory)
01031     {
01032         rv = GetOSXFolderType(kUserDomain, kPictureDocumentsFolderType, getter_AddRefs(localFile));
01033     }
01034     else if (inAtom == nsDirectoryService::sMovieDocumentsDirectory)
01035     {
01036         rv = GetOSXFolderType(kUserDomain, kMovieDocumentsFolderType, getter_AddRefs(localFile));
01037     }
01038     else if (inAtom == nsDirectoryService::sMusicDocumentsDirectory)
01039     {
01040         rv = GetOSXFolderType(kUserDomain, kMusicDocumentsFolderType, getter_AddRefs(localFile));
01041     }
01042     else if (inAtom == nsDirectoryService::sInternetSitesDirectory)
01043     {
01044         rv = GetOSXFolderType(kUserDomain, kInternetSitesFolderType, getter_AddRefs(localFile));
01045     }
01046 #elif defined (XP_WIN)
01047     else if (inAtom == nsDirectoryService::sSystemDirectory)
01048     {
01049         rv = GetSpecialSystemDirectory(Win_SystemDirectory, getter_AddRefs(localFile)); 
01050     }
01051     else if (inAtom == nsDirectoryService::sWindowsDirectory)
01052     {
01053         rv = GetSpecialSystemDirectory(Win_WindowsDirectory, getter_AddRefs(localFile)); 
01054     }
01055     else if (inAtom == nsDirectoryService::sWindowsProgramFiles)
01056     {
01057         rv = GetSpecialSystemDirectory(Win_ProgramFiles, getter_AddRefs(localFile));
01058     }
01059     else if (inAtom == nsDirectoryService::sOS_HomeDirectory)
01060     {
01061         rv = GetSpecialSystemDirectory(Win_HomeDirectory, getter_AddRefs(localFile)); 
01062     }
01063     else if (inAtom == nsDirectoryService::sDesktop)
01064     {
01065         rv = GetSpecialSystemDirectory(Win_Desktop, getter_AddRefs(localFile)); 
01066     }
01067     else if (inAtom == nsDirectoryService::sPrograms)
01068     {
01069         rv = GetSpecialSystemDirectory(Win_Programs, getter_AddRefs(localFile)); 
01070     }
01071     else if (inAtom == nsDirectoryService::sControls)
01072     {
01073         rv = GetSpecialSystemDirectory(Win_Controls, getter_AddRefs(localFile)); 
01074     }
01075     else if (inAtom == nsDirectoryService::sPrinters)
01076     {
01077         rv = GetSpecialSystemDirectory(Win_Printers, getter_AddRefs(localFile)); 
01078     }
01079     else if (inAtom == nsDirectoryService::sPersonal)
01080     {
01081         rv = GetSpecialSystemDirectory(Win_Personal, getter_AddRefs(localFile)); 
01082     }
01083     else if (inAtom == nsDirectoryService::sFavorites)
01084     {
01085         rv = GetSpecialSystemDirectory(Win_Favorites, getter_AddRefs(localFile)); 
01086     }
01087     else if (inAtom == nsDirectoryService::sStartup)
01088     {
01089         rv = GetSpecialSystemDirectory(Win_Startup, getter_AddRefs(localFile));
01090     }
01091     else if (inAtom == nsDirectoryService::sRecent)
01092     {
01093         rv = GetSpecialSystemDirectory(Win_Recent, getter_AddRefs(localFile)); 
01094     }
01095     else if (inAtom == nsDirectoryService::sSendto)
01096     {
01097         rv = GetSpecialSystemDirectory(Win_Sendto, getter_AddRefs(localFile)); 
01098     }
01099     else if (inAtom == nsDirectoryService::sBitbucket)
01100     {
01101         rv = GetSpecialSystemDirectory(Win_Bitbucket, getter_AddRefs(localFile)); 
01102     }
01103     else if (inAtom == nsDirectoryService::sStartmenu)
01104     {
01105         rv = GetSpecialSystemDirectory(Win_Startmenu, getter_AddRefs(localFile)); 
01106     }
01107     else if (inAtom == nsDirectoryService::sDesktopdirectory ||
01108              inAtom == nsDirectoryService::sOS_DesktopDirectory)
01109     {
01110         rv = GetSpecialSystemDirectory(Win_Desktopdirectory, getter_AddRefs(localFile)); 
01111     }
01112     else if (inAtom == nsDirectoryService::sDrives)
01113     {
01114         rv = GetSpecialSystemDirectory(Win_Drives, getter_AddRefs(localFile));
01115     }
01116     else if (inAtom == nsDirectoryService::sNetwork)
01117     {
01118         rv = GetSpecialSystemDirectory(Win_Network, getter_AddRefs(localFile)); 
01119     }
01120     else if (inAtom == nsDirectoryService::sNethood)
01121     {
01122         rv = GetSpecialSystemDirectory(Win_Nethood, getter_AddRefs(localFile)); 
01123     }
01124     else if (inAtom == nsDirectoryService::sFonts)
01125     {
01126         rv = GetSpecialSystemDirectory(Win_Fonts, getter_AddRefs(localFile));
01127     }
01128     else if (inAtom == nsDirectoryService::sTemplates)
01129     {
01130         rv = GetSpecialSystemDirectory(Win_Templates, getter_AddRefs(localFile)); 
01131     }
01132     else if (inAtom == nsDirectoryService::sCommon_Startmenu)
01133     {
01134         rv = GetSpecialSystemDirectory(Win_Common_Startmenu, getter_AddRefs(localFile)); 
01135     }
01136     else if (inAtom == nsDirectoryService::sCommon_Programs)
01137     {
01138         rv = GetSpecialSystemDirectory(Win_Common_Programs, getter_AddRefs(localFile)); 
01139     }
01140     else if (inAtom == nsDirectoryService::sCommon_Startup)
01141     {
01142         rv = GetSpecialSystemDirectory(Win_Common_Startup, getter_AddRefs(localFile)); 
01143     }
01144     else if (inAtom == nsDirectoryService::sCommon_Desktopdirectory)
01145     {
01146         rv = GetSpecialSystemDirectory(Win_Common_Desktopdirectory, getter_AddRefs(localFile)); 
01147     }
01148     else if (inAtom == nsDirectoryService::sAppdata)
01149     {
01150         rv = GetSpecialSystemDirectory(Win_Appdata, getter_AddRefs(localFile)); 
01151     }
01152     else if (inAtom == nsDirectoryService::sLocalAppdata)
01153     {
01154         rv = GetSpecialSystemDirectory(Win_LocalAppdata, getter_AddRefs(localFile)); 
01155     }
01156     else if (inAtom == nsDirectoryService::sPrinthood)
01157     {
01158         rv = GetSpecialSystemDirectory(Win_Printhood, getter_AddRefs(localFile)); 
01159     }
01160     else if (inAtom == nsDirectoryService::sWinCookiesDirectory)
01161     {
01162         rv = GetSpecialSystemDirectory(Win_Cookies, getter_AddRefs(localFile)); 
01163     }
01164 #elif defined (XP_UNIX)
01165 
01166     else if (inAtom == nsDirectoryService::sLocalDirectory)
01167     {
01168         rv = GetSpecialSystemDirectory(Unix_LocalDirectory, getter_AddRefs(localFile)); 
01169     }
01170     else if (inAtom == nsDirectoryService::sLibDirectory)
01171     {
01172         rv = GetSpecialSystemDirectory(Unix_LibDirectory, getter_AddRefs(localFile));
01173     }
01174     else if (inAtom == nsDirectoryService::sOS_HomeDirectory)
01175     {
01176         rv = GetSpecialSystemDirectory(Unix_HomeDirectory, getter_AddRefs(localFile)); 
01177     }
01178     else if (inAtom == nsDirectoryService::sOS_DesktopDirectory)
01179     {
01180         rv = GetSpecialSystemDirectory(Unix_DesktopDirectory, getter_AddRefs(localFile)); 
01181     }
01182 #elif defined (XP_OS2)
01183     else if (inAtom == nsDirectoryService::sSystemDirectory)
01184     {
01185         rv = GetSpecialSystemDirectory(OS2_SystemDirectory, getter_AddRefs(localFile)); 
01186     }
01187     else if (inAtom == nsDirectoryService::sOS2Directory)
01188     {
01189         rv = GetSpecialSystemDirectory(OS2_OS2Directory, getter_AddRefs(localFile)); 
01190     }
01191     else if (inAtom == nsDirectoryService::sOS_HomeDirectory)
01192     {
01193         rv = GetSpecialSystemDirectory(OS2_HomeDirectory, getter_AddRefs(localFile)); 
01194     }
01195     else if (inAtom == nsDirectoryService::sOS_DesktopDirectory)
01196     {
01197         rv = GetSpecialSystemDirectory(OS2_DesktopDirectory, getter_AddRefs(localFile)); 
01198     }
01199 #elif defined (XP_BEOS)
01200     else if (inAtom == nsDirectoryService::sSettingsDirectory)
01201     {
01202         rv = GetSpecialSystemDirectory(BeOS_SettingsDirectory, getter_AddRefs(localFile)); 
01203     }
01204     else if (inAtom == nsDirectoryService::sOS_HomeDirectory)
01205     {
01206         rv = GetSpecialSystemDirectory(BeOS_HomeDirectory, getter_AddRefs(localFile));
01207     }
01208     else if (inAtom == nsDirectoryService::sOS_DesktopDirectory)
01209     {
01210         rv = GetSpecialSystemDirectory(BeOS_DesktopDirectory, getter_AddRefs(localFile)); 
01211     }
01212     else if (inAtom == nsDirectoryService::sSystemDirectory)
01213     {
01214         rv = GetSpecialSystemDirectory(BeOS_SystemDirectory, getter_AddRefs(localFile)); 
01215     }
01216 #endif
01217 
01218 
01219     NS_RELEASE(inAtom);
01220 
01221        if (localFile && NS_SUCCEEDED(rv))
01222               return localFile->QueryInterface(NS_GET_IID(nsIFile), (void**)_retval);
01223 #ifdef DEBUG_dougt
01224     printf("Failed to find directory for key: %s\n", prop);
01225 #endif
01226        return rv;
01227 }
01228 
01229 NS_IMETHODIMP
01230 nsDirectoryService::GetFiles(const char *prop, nsISimpleEnumerator **_retval)
01231 {
01232     NS_ENSURE_ARG_POINTER(_retval);
01233     *_retval = nsnull;
01234         
01235     return NS_ERROR_FAILURE;
01236 }