Back to index

lightning-sunbird  0.9+nobinonly
nsProfileDirServiceProvider.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
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) 2002
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Conrad Carlen <ccarlen@netscape.com>
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either the GNU General Public License Version 2 or later (the "GPL"), or
00027  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 #include "nsProfileDirServiceProvider.h"
00040 #include "nsProfileStringTypes.h"
00041 #include "nsProfileLock.h"
00042 #include "nsILocalFile.h"
00043 #include "nsDirectoryServiceDefs.h"
00044 #include "nsAppDirectoryServiceDefs.h"
00045 #include "nsISupportsUtils.h"
00046 #include "nsISimpleEnumerator.h"
00047 #include "nsIObserverService.h"
00048 
00049 #ifdef MOZ_PROFILESHARING
00050 #include "nsIProfileSharingSetup.h"
00051 #include "ipcITransactionService.h"
00052 #endif
00053 
00054 // File Name Defines
00055 
00056 #define PREFS_FILE_50_NAME           NS_LITERAL_CSTRING("prefs.js")
00057 #define USER_CHROME_DIR_50_NAME      NS_LITERAL_CSTRING("chrome")
00058 #define LOCAL_STORE_FILE_50_NAME     NS_LITERAL_CSTRING("localstore.rdf")
00059 #define HISTORY_FILE_50_NAME         NS_LITERAL_CSTRING("history.dat")
00060 #define PANELS_FILE_50_NAME          NS_LITERAL_CSTRING("panels.rdf")
00061 #define MIME_TYPES_FILE_50_NAME      NS_LITERAL_CSTRING("mimeTypes.rdf")
00062 #define BOOKMARKS_FILE_50_NAME       NS_LITERAL_CSTRING("bookmarks.html")
00063 #define DOWNLOADS_FILE_50_NAME       NS_LITERAL_CSTRING("downloads.rdf")
00064 #define SEARCH_FILE_50_NAME          NS_LITERAL_CSTRING("search.rdf" )
00065 #define MAIL_DIR_50_NAME             NS_LITERAL_CSTRING("Mail")
00066 #define IMAP_MAIL_DIR_50_NAME        NS_LITERAL_CSTRING("ImapMail")
00067 #define NEWS_DIR_50_NAME             NS_LITERAL_CSTRING("News")
00068 #define MSG_FOLDER_CACHE_DIR_50_NAME NS_LITERAL_CSTRING("panacea.dat")
00069 #define STORAGE_FILE_50_NAME         NS_LITERAL_CSTRING("storage.sdb")
00070 
00071 //*****************************************************************************
00072 // nsProfileDirServiceProvider::nsProfileDirServiceProvider
00073 //*****************************************************************************
00074 
00075 nsProfileDirServiceProvider::nsProfileDirServiceProvider(PRBool aNotifyObservers) :
00076 #ifdef MOZ_PROFILELOCKING
00077   mProfileDirLock(nsnull),
00078 #endif
00079   mNotifyObservers(aNotifyObservers),
00080   mSharingEnabled(PR_FALSE)
00081 {
00082 }
00083 
00084 
00085 nsProfileDirServiceProvider::~nsProfileDirServiceProvider()
00086 {
00087 #ifdef MOZ_PROFILELOCKING
00088   delete mProfileDirLock;
00089 #endif
00090 }
00091 
00092 nsresult
00093 nsProfileDirServiceProvider::SetProfileDir(nsIFile* aProfileDir,
00094                                            nsIFile* aLocalProfileDir)
00095 {
00096   if (!aLocalProfileDir)
00097     aLocalProfileDir = aProfileDir;
00098   if (mProfileDir) {
00099     PRBool isEqual;
00100     if (aProfileDir &&
00101         NS_SUCCEEDED(aProfileDir->Equals(mProfileDir, &isEqual)) && isEqual) {
00102       NS_WARNING("Setting profile dir to same as current");
00103       return NS_OK;
00104     }
00105 #ifdef MOZ_PROFILELOCKING
00106     mProfileDirLock->Unlock();
00107 #endif
00108     UndefineFileLocations();
00109   }
00110   mProfileDir = aProfileDir;
00111   mLocalProfileDir = aLocalProfileDir;
00112   if (!mProfileDir)
00113     return NS_OK;
00114 
00115   nsresult rv = InitProfileDir(mProfileDir);
00116   if (NS_FAILED(rv))
00117     return rv;
00118 
00119   // Make sure that the local profile dir exists
00120   // we just try to create it - if it exists already, that'll fail; ignore
00121   // errors
00122   mLocalProfileDir->Create(nsIFile::DIRECTORY_TYPE, 0700);
00123 
00124 #ifdef MOZ_PROFILESHARING
00125   if (mSharingEnabled) {
00126     nsCOMPtr<ipcITransactionService> transServ =
00127         do_GetService(IPC_TRANSACTIONSERVICE_CONTRACTID, &rv);
00128     if (NS_SUCCEEDED(rv)) {
00129       nsCAutoString nativePath;
00130       rv = mProfileDir->GetNativePath(nativePath);
00131       if (NS_SUCCEEDED(rv))
00132         rv = transServ->Init(nativePath);
00133     }
00134     if (NS_FAILED(rv)) {
00135       NS_WARNING("Unable to initialize transaction service");
00136     }
00137   }
00138 #endif
00139 
00140 #ifdef MOZ_PROFILELOCKING
00141   // Lock the non-shared sub-dir if we are sharing,
00142   // the whole profile dir if we are not.
00143   nsCOMPtr<nsILocalFile> dirToLock;
00144   if (mSharingEnabled)
00145     dirToLock = do_QueryInterface(mNonSharedProfileDir);
00146   else
00147     dirToLock = do_QueryInterface(mProfileDir);
00148   rv = mProfileDirLock->Lock(dirToLock, nsnull);
00149   if (NS_FAILED(rv))
00150     return rv;
00151 #endif
00152 
00153   if (mNotifyObservers) {
00154     nsCOMPtr<nsIObserverService> observerService =
00155              do_GetService("@mozilla.org/observer-service;1");
00156     if (!observerService)
00157       return NS_ERROR_FAILURE;
00158 
00159     NS_NAMED_LITERAL_STRING(context, "startup");
00160     // Notify observers that the profile has changed - Here they respond to new profile
00161     observerService->NotifyObservers(nsnull, "profile-do-change", context.get());
00162     // Now observers can respond to something another observer did on "profile-do-change"
00163     observerService->NotifyObservers(nsnull, "profile-after-change", context.get());
00164   }
00165 
00166   return NS_OK;
00167 }
00168 
00169 nsresult
00170 nsProfileDirServiceProvider::Register()
00171 {
00172   nsCOMPtr<nsIDirectoryService> directoryService =
00173           do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID);
00174   if (!directoryService)
00175     return NS_ERROR_FAILURE;
00176   return directoryService->RegisterProvider(this);
00177 }
00178 
00179 nsresult
00180 nsProfileDirServiceProvider::Shutdown()
00181 {
00182   if (!mNotifyObservers)
00183     return NS_OK;
00184 
00185   nsCOMPtr<nsIObserverService> observerService =
00186            do_GetService("@mozilla.org/observer-service;1");
00187   if (!observerService)
00188     return NS_ERROR_FAILURE;
00189 
00190   NS_NAMED_LITERAL_STRING(context, "shutdown-persist");
00191   observerService->NotifyObservers(nsnull, "profile-before-change", context.get());
00192   return NS_OK;
00193 }
00194 
00195 //*****************************************************************************
00196 // nsProfileDirServiceProvider::nsISupports
00197 //*****************************************************************************
00198 
00199 NS_IMPL_THREADSAFE_ISUPPORTS1(nsProfileDirServiceProvider,
00200                               nsIDirectoryServiceProvider)
00201 
00202 //*****************************************************************************
00203 // nsProfileDirServiceProvider::nsIDirectoryServiceProvider
00204 //*****************************************************************************
00205 
00206 NS_IMETHODIMP
00207 nsProfileDirServiceProvider::GetFile(const char *prop, PRBool *persistant, nsIFile **_retval)
00208 {
00209   NS_ENSURE_ARG(prop);
00210   NS_ENSURE_ARG_POINTER(persistant);
00211   NS_ENSURE_ARG_POINTER(_retval);
00212 
00213   // Don't assert - we can be called many times before SetProfileDir() has been called.
00214   if (!mProfileDir)
00215     return NS_ERROR_FAILURE;
00216 
00217   *persistant = PR_TRUE;
00218   nsIFile* domainDir = mProfileDir;
00219 
00220 #ifdef MOZ_PROFILESHARING
00221   // If the prop is prefixed with NS_SHARED,
00222   // the location is in the shared domain.
00223   PRBool bUseShared = PR_FALSE;
00224   if (strncmp(prop, NS_SHARED, sizeof(NS_SHARED)-1) == 0) {
00225     prop += (sizeof(NS_SHARED)-1);
00226     bUseShared = PR_TRUE;
00227   }
00228   if (!bUseShared && mNonSharedProfileDir)
00229     domainDir = mNonSharedProfileDir;
00230 #endif
00231 
00232   nsCOMPtr<nsIFile>  localFile;
00233   nsresult rv = NS_ERROR_FAILURE;
00234 
00235   if (strcmp(prop, NS_APP_PREFS_50_DIR) == 0) {
00236     rv = domainDir->Clone(getter_AddRefs(localFile));
00237   }
00238   else if (strcmp(prop, NS_APP_PREFS_50_FILE) == 0) {
00239     rv = domainDir->Clone(getter_AddRefs(localFile));
00240     if (NS_SUCCEEDED(rv))
00241       rv = localFile->AppendNative(PREFS_FILE_50_NAME);
00242   }
00243   else if (strcmp(prop, NS_APP_USER_PROFILE_50_DIR) == 0) {
00244     rv = domainDir->Clone(getter_AddRefs(localFile));
00245   }
00246   else if (strcmp(prop, NS_APP_USER_PROFILE_LOCAL_50_DIR) == 0) {
00247     rv = mLocalProfileDir->Clone(getter_AddRefs(localFile));
00248   }
00249   else if (strcmp(prop, NS_APP_USER_CHROME_DIR) == 0) {
00250     rv = domainDir->Clone(getter_AddRefs(localFile));
00251     if (NS_SUCCEEDED(rv))
00252       rv = localFile->AppendNative(USER_CHROME_DIR_50_NAME);
00253   }
00254   else if (strcmp(prop, NS_APP_LOCALSTORE_50_FILE) == 0) {
00255     rv = domainDir->Clone(getter_AddRefs(localFile));
00256     if (NS_SUCCEEDED(rv)) {
00257       rv = localFile->AppendNative(LOCAL_STORE_FILE_50_NAME);
00258       if (NS_SUCCEEDED(rv)) {
00259         // it's OK if we can't copy the file... it will be created
00260         // by client code.
00261         (void) EnsureProfileFileExists(localFile, domainDir);
00262       }
00263     }
00264   }
00265   else if (strcmp(prop, NS_APP_HISTORY_50_FILE) == 0) {
00266     rv = domainDir->Clone(getter_AddRefs(localFile));
00267     if (NS_SUCCEEDED(rv))
00268       rv = localFile->AppendNative(HISTORY_FILE_50_NAME);
00269   }
00270   else if (strcmp(prop, NS_APP_USER_PANELS_50_FILE) == 0) {
00271     rv = domainDir->Clone(getter_AddRefs(localFile));
00272     if (NS_SUCCEEDED(rv)) {
00273       rv = localFile->AppendNative(PANELS_FILE_50_NAME);
00274       if (NS_SUCCEEDED(rv))
00275         rv = EnsureProfileFileExists(localFile, domainDir);
00276     }
00277   }
00278   else if (strcmp(prop, NS_APP_USER_MIMETYPES_50_FILE) == 0) {
00279     rv = domainDir->Clone(getter_AddRefs(localFile));
00280     if (NS_SUCCEEDED(rv)) {
00281       rv = localFile->AppendNative(MIME_TYPES_FILE_50_NAME);
00282       if (NS_SUCCEEDED(rv))
00283         rv = EnsureProfileFileExists(localFile, domainDir);
00284     }
00285   }
00286   else if (strcmp(prop, NS_APP_BOOKMARKS_50_FILE) == 0) {
00287     rv = domainDir->Clone(getter_AddRefs(localFile));
00288     if (NS_SUCCEEDED(rv))
00289       rv = localFile->AppendNative(BOOKMARKS_FILE_50_NAME);
00290   }
00291   else if (strcmp(prop, NS_APP_DOWNLOADS_50_FILE) == 0) {
00292     rv = domainDir->Clone(getter_AddRefs(localFile));
00293     if (NS_SUCCEEDED(rv))
00294       rv = localFile->AppendNative(DOWNLOADS_FILE_50_NAME);
00295   }
00296   else if (strcmp(prop, NS_APP_SEARCH_50_FILE) == 0) {
00297     rv = domainDir->Clone(getter_AddRefs(localFile));
00298     if (NS_SUCCEEDED(rv)) {
00299       rv = localFile->AppendNative(SEARCH_FILE_50_NAME);
00300       if (NS_SUCCEEDED(rv))
00301         rv = EnsureProfileFileExists(localFile, domainDir);
00302     }
00303   }
00304   else if (strcmp(prop, NS_APP_MAIL_50_DIR) == 0) {
00305     rv = domainDir->Clone(getter_AddRefs(localFile));
00306     if (NS_SUCCEEDED(rv))
00307       rv = localFile->AppendNative(MAIL_DIR_50_NAME);
00308   }
00309   else if (strcmp(prop, NS_APP_IMAP_MAIL_50_DIR) == 0) {
00310     rv = domainDir->Clone(getter_AddRefs(localFile));
00311     if (NS_SUCCEEDED(rv))
00312       rv = localFile->AppendNative(IMAP_MAIL_DIR_50_NAME);
00313   }
00314   else if (strcmp(prop, NS_APP_NEWS_50_DIR) == 0) {
00315     rv = domainDir->Clone(getter_AddRefs(localFile));
00316     if (NS_SUCCEEDED(rv))
00317       rv = localFile->AppendNative(NEWS_DIR_50_NAME);
00318   }
00319   else if (strcmp(prop, NS_APP_MESSENGER_FOLDER_CACHE_50_DIR) == 0) {
00320     rv = domainDir->Clone(getter_AddRefs(localFile));
00321     if (NS_SUCCEEDED(rv))
00322       rv = localFile->AppendNative(MSG_FOLDER_CACHE_DIR_50_NAME);
00323   }
00324   else if (strcmp(prop, NS_APP_STORAGE_50_FILE) == 0) {
00325     rv = domainDir->Clone(getter_AddRefs(localFile));
00326     if (NS_SUCCEEDED(rv))
00327       rv = localFile->AppendNative(STORAGE_FILE_50_NAME);
00328   }
00329 
00330   
00331   if (localFile && NS_SUCCEEDED(rv))
00332     return CallQueryInterface(localFile, _retval);
00333 
00334   return rv;
00335 }
00336 
00337 //*****************************************************************************
00338 // Protected methods
00339 //*****************************************************************************
00340 
00341 nsresult
00342 nsProfileDirServiceProvider::Initialize()
00343 {
00344 #ifdef MOZ_PROFILELOCKING
00345   mProfileDirLock = new nsProfileLock;
00346   if (!mProfileDirLock)
00347     return NS_ERROR_OUT_OF_MEMORY;
00348 #endif
00349 
00350 #ifdef MOZ_PROFILESHARING
00351   nsCOMPtr<nsIProfileSharingSetup> sharingSetup =
00352       do_GetService("@mozilla.org/embedcomp/profile-sharing-setup;1");
00353   if (sharingSetup) {
00354     PRBool tempBool;
00355     if (NS_SUCCEEDED(sharingSetup->GetIsSharingEnabled(&tempBool)))
00356       mSharingEnabled = tempBool;
00357     if (mSharingEnabled)
00358       sharingSetup->GetClientName(mNonSharedDirName);
00359   }
00360 #endif
00361 
00362   return NS_OK;
00363 }
00364 
00365 nsresult
00366 nsProfileDirServiceProvider::InitProfileDir(nsIFile *profileDir)
00367 {
00368   // Make sure our "Profile" folder exists.
00369   // If it does not, copy the profile defaults to its location.
00370 
00371   nsresult rv;
00372   PRBool exists;
00373   rv = profileDir->Exists(&exists);
00374   if (NS_FAILED(rv))
00375     return rv;
00376 
00377   if (!exists) {
00378     nsCOMPtr<nsIFile> profileDefaultsDir;
00379     nsCOMPtr<nsIFile> profileDirParent;
00380     nsCAutoString profileDirName;
00381 
00382     (void)profileDir->GetParent(getter_AddRefs(profileDirParent));
00383     if (!profileDirParent)
00384       return NS_ERROR_FAILURE;
00385     rv = profileDir->GetNativeLeafName(profileDirName);
00386     if (NS_FAILED(rv))
00387       return rv;
00388 
00389     rv = NS_GetSpecialDirectory(NS_APP_PROFILE_DEFAULTS_50_DIR, getter_AddRefs(profileDefaultsDir));
00390     if (NS_FAILED(rv)) {
00391       rv = NS_GetSpecialDirectory(NS_APP_PROFILE_DEFAULTS_NLOC_50_DIR, getter_AddRefs(profileDefaultsDir));
00392       if (NS_FAILED(rv))
00393         return rv;
00394     }
00395     rv = profileDefaultsDir->CopyToNative(profileDirParent, profileDirName);
00396     if (NS_FAILED(rv)) {
00397         // if copying failed, lets just ensure that the profile directory exists.
00398         profileDirParent->AppendNative(profileDirName);
00399         rv = profileDirParent->Create(nsIFile::DIRECTORY_TYPE, 0700);
00400         if (NS_FAILED(rv))
00401             return rv;
00402     }
00403 
00404 #if !defined(XP_MAC) && !defined(WINCE)
00405     rv = profileDir->SetPermissions(0700);
00406     if (NS_FAILED(rv))
00407       return rv;
00408 #endif
00409 
00410   }
00411   else {
00412     PRBool isDir;
00413     rv = profileDir->IsDirectory(&isDir);
00414 
00415     if (NS_FAILED(rv))
00416       return rv;
00417     if (!isDir)
00418       return NS_ERROR_FILE_NOT_DIRECTORY;
00419   }
00420 
00421   if (mNonSharedDirName.Length())
00422     rv = InitNonSharedProfileDir();
00423 
00424   return rv;
00425 }
00426 
00427 nsresult
00428 nsProfileDirServiceProvider::InitNonSharedProfileDir()
00429 {
00430   nsresult rv;
00431 
00432   NS_ENSURE_STATE(mProfileDir);
00433   NS_ENSURE_STATE(mNonSharedDirName.Length());
00434 
00435   nsCOMPtr<nsIFile> localDir;
00436   rv = mProfileDir->Clone(getter_AddRefs(localDir));
00437   if (NS_SUCCEEDED(rv)) {
00438     rv = localDir->Append(mNonSharedDirName);
00439     if (NS_SUCCEEDED(rv)) {
00440       PRBool exists;
00441       rv = localDir->Exists(&exists);
00442       if (NS_SUCCEEDED(rv)) {
00443         if (!exists) {
00444           rv = localDir->Create(nsIFile::DIRECTORY_TYPE, 0700);
00445         }
00446         else {
00447           PRBool isDir;
00448           rv = localDir->IsDirectory(&isDir);
00449           if (NS_SUCCEEDED(rv)) {
00450             if (!isDir)
00451               rv = NS_ERROR_FILE_NOT_DIRECTORY;
00452           }
00453         }
00454         if (NS_SUCCEEDED(rv))
00455           mNonSharedProfileDir = localDir;
00456       }
00457     }
00458   }
00459   return rv;
00460 }
00461 
00462 nsresult
00463 nsProfileDirServiceProvider::EnsureProfileFileExists(nsIFile *aFile, nsIFile *destDir)
00464 {
00465   nsresult rv;
00466   PRBool exists;
00467 
00468   rv = aFile->Exists(&exists);
00469   if (NS_FAILED(rv))
00470     return rv;
00471   if (exists)
00472     return NS_OK;
00473 
00474   nsCOMPtr<nsIFile> defaultsFile;
00475 
00476   // Attempt first to get the localized subdir of the defaults
00477   rv = NS_GetSpecialDirectory(NS_APP_PROFILE_DEFAULTS_50_DIR, getter_AddRefs(defaultsFile));
00478   if (NS_FAILED(rv)) {
00479     // If that has not been defined, use the top level of the defaults
00480     rv = NS_GetSpecialDirectory(NS_APP_PROFILE_DEFAULTS_NLOC_50_DIR, getter_AddRefs(defaultsFile));
00481     if (NS_FAILED(rv))
00482       return rv;
00483   }
00484 
00485   nsCAutoString leafName;
00486   rv = aFile->GetNativeLeafName(leafName);
00487   if (NS_FAILED(rv))
00488     return rv;
00489   rv = defaultsFile->AppendNative(leafName);
00490   if (NS_FAILED(rv))
00491     return rv;
00492   
00493   return defaultsFile->CopyTo(destDir, EmptyString());
00494 }
00495 
00496 nsresult
00497 nsProfileDirServiceProvider::UndefineFileLocations()
00498 {
00499   nsresult rv;
00500 
00501   nsCOMPtr<nsIProperties> directoryService =
00502            do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv);
00503   NS_ENSURE_TRUE(directoryService, NS_ERROR_FAILURE);
00504 
00505   (void) directoryService->Undefine(NS_APP_PREFS_50_DIR);
00506   (void) directoryService->Undefine(NS_APP_PREFS_50_FILE);
00507   (void) directoryService->Undefine(NS_APP_USER_PROFILE_50_DIR);
00508   (void) directoryService->Undefine(NS_APP_USER_CHROME_DIR);
00509   (void) directoryService->Undefine(NS_APP_LOCALSTORE_50_FILE);
00510   (void) directoryService->Undefine(NS_APP_HISTORY_50_FILE);
00511   (void) directoryService->Undefine(NS_APP_USER_PANELS_50_FILE);
00512   (void) directoryService->Undefine(NS_APP_USER_MIMETYPES_50_FILE);
00513   (void) directoryService->Undefine(NS_APP_BOOKMARKS_50_FILE);
00514   (void) directoryService->Undefine(NS_APP_DOWNLOADS_50_FILE);
00515   (void) directoryService->Undefine(NS_APP_SEARCH_50_FILE);
00516   (void) directoryService->Undefine(NS_APP_MAIL_50_DIR);
00517   (void) directoryService->Undefine(NS_APP_IMAP_MAIL_50_DIR);
00518   (void) directoryService->Undefine(NS_APP_NEWS_50_DIR);
00519   (void) directoryService->Undefine(NS_APP_MESSENGER_FOLDER_CACHE_50_DIR);
00520 
00521   return NS_OK;
00522 }
00523 
00524 //*****************************************************************************
00525 // Global creation function
00526 //*****************************************************************************
00527 
00528 nsresult NS_NewProfileDirServiceProvider(PRBool aNotifyObservers,
00529                                          nsProfileDirServiceProvider** aProvider)
00530 {
00531   NS_ENSURE_ARG_POINTER(aProvider);
00532   *aProvider = nsnull;
00533 
00534   nsProfileDirServiceProvider *prov = new nsProfileDirServiceProvider(aNotifyObservers);
00535   if (!prov)
00536     return NS_ERROR_OUT_OF_MEMORY;
00537   nsresult rv = prov->Initialize();
00538   if (NS_FAILED(rv)) {
00539     delete prov;
00540     return rv;
00541   }
00542   NS_ADDREF(*aProvider = prov);
00543   return NS_OK;
00544 }