From afbbb2afc0b01373afc5eddb31c6110c4c0a75d4 Mon Sep 17 00:00:00 2001 From: "racham%netscape.com" Date: Wed, 16 Aug 2000 22:40:27 +0000 Subject: [PATCH] Fixing bug 46320. Reducing the number of global files by moving profile registry to product sub-directory under HOME. r=dougt git-svn-id: svn://10.0.0.236/trunk@76450 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/modules/libreg/xpcom/nsRegistry.cpp | 86 +++++++++- mozilla/xpcom/build/nsXPComInit.cpp | 19 ++ .../xpcom/components/nsComponentManager.cpp | 50 ------ mozilla/xpcom/components/nsIServiceManager.h | 3 + .../components/nsNativeComponentLoader.cpp | 5 +- mozilla/xpcom/components/nsRegistry.cpp | 86 +++++++++- mozilla/xpcom/io/nsDirectoryService.cpp | 162 +++++++++++++----- mozilla/xpcom/io/nsDirectoryService.h | 12 +- mozilla/xpcom/io/nsDirectoryServiceDefs.h | 3 + mozilla/xpcom/io/nsIDirectoryService.idl | 1 + mozilla/xpcom/io/nsSpecialSystemDirectory.cpp | 20 ++- 11 files changed, 340 insertions(+), 107 deletions(-) diff --git a/mozilla/modules/libreg/xpcom/nsRegistry.cpp b/mozilla/modules/libreg/xpcom/nsRegistry.cpp index 11ad5edb050..7761ab8f622 100644 --- a/mozilla/modules/libreg/xpcom/nsRegistry.cpp +++ b/mozilla/modules/libreg/xpcom/nsRegistry.cpp @@ -36,6 +36,8 @@ #include "nsIServiceManager.h" #include "nsTextFormatter.h" +#include "nsComponentManager.h" + /* extra locking for the paranoid */ /* #define EXTRA_THREADSAFE */ #ifndef EXTRA_THREADSAFE @@ -43,6 +45,10 @@ #define PR_Unlock(x) (void)0 #endif +// Logging of debug output +#define FORCE_PR_LOG /* Allow logging in the release build */ +extern PRLogModuleInfo *nsComponentManagerLog; + PRUnichar widestrFormat[] = { PRUnichar('%'),PRUnichar('s'),PRUnichar(0)}; /*-------------------------------- nsRegistry ---------------------------------- @@ -416,9 +422,62 @@ NS_IMETHODIMP nsRegistry::Open( const char *regFile ) { | Takes a registry id and maps that to a file name for opening. We first check | | to see if a registry file is already open and close it if so. | ------------------------------------------------------------------------------*/ -NS_IMETHODIMP nsRegistry::OpenWellKnownRegistry( nsWellKnownRegistry regid ) { +NS_IMETHODIMP nsRegistry::OpenWellKnownRegistry( nsWellKnownRegistry regid ) +{ REGERR err = REGERR_OK; + + #ifdef XP_UNIX + // Create ~/.mozilla as that is the default place for the registry file + + /* The default registry on the unix system is $HOME/.mozilla/registry per + * vr_findGlobalRegName(). vr_findRegFile() will create the registry file + * if it doesn't exist. But it wont create directories. + * + * Hence we need to create the directory if it doesn't exist already. + * + * Why create it here as opposed to the app ? + * ------------------------------------------ + * The app cannot create the directory in main() as most of the registry + * and initialization happens due to use of static variables. + * And we dont want to be dependent on the order in which + * these static stuff happen. + * + * Permission for the $HOME/.mozilla will be Read,Write,Execute + * for user only. Nothing to group and others. + */ + char *home = getenv("HOME"); + if (home != NULL) + { + char dotMozillaDir[1024]; + PR_snprintf(dotMozillaDir, sizeof(dotMozillaDir), + "%s/" NS_MOZILLA_DIR_NAME, home); + if (PR_Access(dotMozillaDir, PR_ACCESS_EXISTS) != PR_SUCCESS) + { + PR_MkDir(dotMozillaDir, NS_MOZILLA_DIR_PERMISSION); + PR_LOG(nsComponentManagerLog, PR_LOG_ALWAYS, + ("nsComponentManager: Creating Directory %s", dotMozillaDir)); + } + } +#endif /* XP_UNIX */ + +#ifdef XP_BEOS + BPath p; + const char *settings = "/boot/home/config/settings"; + if(find_directory(B_USER_SETTINGS_DIRECTORY, &p) == B_OK) + settings = p.Path(); + char settingsMozillaDir[1024]; + PR_snprintf(settingsMozillaDir, sizeof(settingsMozillaDir), + "%s/" NS_MOZILLA_DIR_NAME, settings); + if (PR_Access(settingsMozillaDir, PR_ACCESS_EXISTS) != PR_SUCCESS) { + PR_MkDir(settingsMozillaDir, NS_MOZILLA_DIR_PERMISSION); + printf("nsComponentManager: Creating Directory %s\n", settingsMozillaDir); + PR_LOG(nsComponentManagerLog, PR_LOG_ALWAYS, + ("nsComponentManager: Creating Directory %s", settingsMozillaDir)); + } +#endif + + if (mCurRegID != nsIRegistry::None && mCurRegID != regid) { // Cant open another registry without closing explictly. @@ -440,6 +499,8 @@ NS_IMETHODIMP nsRegistry::OpenWellKnownRegistry( nsWellKnownRegistry regid ) { switch ( (nsWellKnownRegistry) regid ) { case ApplicationComponentRegistry: { + // can't use NS_GetSpecialDirectory here. Called before service manager is initialized. + nsCOMPtr directoryService; rv = nsDirectoryService::Create(nsnull, NS_GET_IID(nsIProperties), @@ -447,7 +508,7 @@ NS_IMETHODIMP nsRegistry::OpenWellKnownRegistry( nsWellKnownRegistry regid ) { if (NS_FAILED(rv)) return rv; directoryService->Get(NS_XPCOM_COMPONENT_REGISTRY_FILE, NS_GET_IID(nsIFile), getter_AddRefs(registryLocation)); - + if (registryLocation) { foundReg = PR_TRUE; @@ -462,8 +523,25 @@ NS_IMETHODIMP nsRegistry::OpenWellKnownRegistry( nsWellKnownRegistry regid ) { break; case ApplicationRegistry: { - foundReg = PR_TRUE; - // NULL regFile will open the right one for this case. + // can't use NS_GetSpecialDirectory here. Called before service manager is initialized. + + nsCOMPtr directoryService; + rv = nsDirectoryService::Create(nsnull, + NS_GET_IID(nsIProperties), + getter_AddRefs(directoryService)); + if (NS_FAILED(rv)) return rv; + directoryService->Get(NS_XPCOM_APPLICATION_REGISTRY_FILE, NS_GET_IID(nsIFile), + getter_AddRefs(registryLocation)); + + if (registryLocation) + { + foundReg = PR_TRUE; + registryLocation->GetPath(®File); // dougt fix... + // dveditz needs to fix his registry so that I can pass an + // nsIFile interface and not hack + if (!regFile) + return NS_ERROR_OUT_OF_MEMORY; + } } break; diff --git a/mozilla/xpcom/build/nsXPComInit.cpp b/mozilla/xpcom/build/nsXPComInit.cpp index 008c9f247a9..c8ccba5756f 100644 --- a/mozilla/xpcom/build/nsXPComInit.cpp +++ b/mozilla/xpcom/build/nsXPComInit.cpp @@ -193,7 +193,16 @@ nsIProperties *gDirectoryService = NULL; extern nsIServiceManager* gServiceManager; extern PRBool gShuttingDown; + nsresult NS_COM NS_InitXPCOM(nsIServiceManager* *result, + nsIFile* binDirectory) +{ + return NS_InitXPCOM2(nsnull, result, binDirectory); +} + + +nsresult NS_COM NS_InitXPCOM2(const char* productName, + nsIServiceManager* *result, nsIFile* binDirectory ) { @@ -232,6 +241,16 @@ nsresult NS_COM NS_InitXPCOM(nsIServiceManager* *result, NS_GET_IID(nsIProperties), (void**)&gDirectoryService); + if (NS_FAILED(rv)) + return rv; + + nsCOMPtr dirService = do_QueryInterface(gDirectoryService); + + if (!dirService) + return NS_ERROR_NO_INTERFACE; + + rv = dirService->Init(productName); + if (NS_FAILED(rv)) return rv; diff --git a/mozilla/xpcom/components/nsComponentManager.cpp b/mozilla/xpcom/components/nsComponentManager.cpp index 35f303c0cdd..f222720c2e7 100644 --- a/mozilla/xpcom/components/nsComponentManager.cpp +++ b/mozilla/xpcom/components/nsComponentManager.cpp @@ -419,56 +419,6 @@ nsComponentManagerImpl::PlatformInit(void) } } -#ifdef XP_UNIX - // Create ~/.mozilla as that is the default place for the registry file - - /* The default registry on the unix system is $HOME/.mozilla/registry per - * vr_findGlobalRegName(). vr_findRegFile() will create the registry file - * if it doesn't exist. But it wont create directories. - * - * Hence we need to create the directory if it doesn't exist already. - * - * Why create it here as opposed to the app ? - * ------------------------------------------ - * The app cannot create the directory in main() as most of the registry - * and initialization happens due to use of static variables. - * And we dont want to be dependent on the order in which - * these static stuff happen. - * - * Permission for the $HOME/.mozilla will be Read,Write,Execute - * for user only. Nothing to group and others. - */ - char *home = getenv("HOME"); - if (home != NULL) - { - char dotMozillaDir[1024]; - PR_snprintf(dotMozillaDir, sizeof(dotMozillaDir), - "%s/" NS_MOZILLA_DIR_NAME, home); - if (PR_Access(dotMozillaDir, PR_ACCESS_EXISTS) != PR_SUCCESS) - { - PR_MkDir(dotMozillaDir, NS_MOZILLA_DIR_PERMISSION); - PR_LOG(nsComponentManagerLog, PR_LOG_ALWAYS, - ("nsComponentManager: Creating Directory %s", dotMozillaDir)); - } - } -#endif /* XP_UNIX */ - -#ifdef XP_BEOS - BPath p; - const char *settings = "/boot/home/config/settings"; - if(find_directory(B_USER_SETTINGS_DIRECTORY, &p) == B_OK) - settings = p.Path(); - char settingsMozillaDir[1024]; - PR_snprintf(settingsMozillaDir, sizeof(settingsMozillaDir), - "%s/" NS_MOZILLA_DIR_NAME, settings); - if (PR_Access(settingsMozillaDir, PR_ACCESS_EXISTS) != PR_SUCCESS) { - PR_MkDir(settingsMozillaDir, NS_MOZILLA_DIR_PERMISSION); - printf("nsComponentManager: Creating Directory %s\n", settingsMozillaDir); - PR_LOG(nsComponentManagerLog, PR_LOG_ALWAYS, - ("nsComponentManager: Creating Directory %s", settingsMozillaDir)); - } -#endif - // Open the App Components registry. We will keep it open forever! rv = mRegistry->OpenWellKnownRegistry(nsIRegistry::ApplicationComponentRegistry); if (NS_FAILED(rv)) return rv; diff --git a/mozilla/xpcom/components/nsIServiceManager.h b/mozilla/xpcom/components/nsIServiceManager.h index 3462765225a..2f06097ae65 100644 --- a/mozilla/xpcom/components/nsIServiceManager.h +++ b/mozilla/xpcom/components/nsIServiceManager.h @@ -368,6 +368,9 @@ NS_NewServiceManager(nsIServiceManager* *result); extern NS_COM nsresult NS_InitXPCOM(nsIServiceManager* *result, nsIFile* binDirectory); +extern NS_COM nsresult +NS_InitXPCOM2(const char* productName, nsIServiceManager* *result, nsIFile* binDirectory); + //////////////////////////////////////////////////////////////////////////////// // Shutdown of XPCOM. XPCOM hosts an observer (NS_XPCOM_SHUTDOWN_OBSERVER_ID) // for modules to observer the shutdown. The first thing NS_ShutdownXPCOM() diff --git a/mozilla/xpcom/components/nsNativeComponentLoader.cpp b/mozilla/xpcom/components/nsNativeComponentLoader.cpp index 85d21d7b81d..fcc1af30376 100644 --- a/mozilla/xpcom/components/nsNativeComponentLoader.cpp +++ b/mozilla/xpcom/components/nsNativeComponentLoader.cpp @@ -220,7 +220,7 @@ nsNativeComponentLoader::Init(nsIComponentManager *aCompMgr, nsISupports *aReg) // Get key associated with library nsRegistryKey libKey; rv = node->GetKey(&libKey); - if (!NS_FAILED(rv)) // Cannot continue here, because we have to free unescape + if (NS_SUCCEEDED(rv)) // Cannot continue here, because we have to free unescape { // Create nsDll with this name nsDll *dll = NULL; @@ -229,8 +229,7 @@ nsNativeComponentLoader::Init(nsIComponentManager *aCompMgr, nsISupports *aReg) GetRegistryDllInfo(libKey, &lastModTime, &fileSize); rv = CreateDll(NULL, uLibrary, &lastModTime, &fileSize, &dll); } - if (uLibrary != eLibrary - && uLibrary != nsnull) + if (uLibrary && (uLibrary != eLibrary)) nsMemory::Free(uLibrary); if (NS_FAILED(rv)) continue; diff --git a/mozilla/xpcom/components/nsRegistry.cpp b/mozilla/xpcom/components/nsRegistry.cpp index 11ad5edb050..7761ab8f622 100644 --- a/mozilla/xpcom/components/nsRegistry.cpp +++ b/mozilla/xpcom/components/nsRegistry.cpp @@ -36,6 +36,8 @@ #include "nsIServiceManager.h" #include "nsTextFormatter.h" +#include "nsComponentManager.h" + /* extra locking for the paranoid */ /* #define EXTRA_THREADSAFE */ #ifndef EXTRA_THREADSAFE @@ -43,6 +45,10 @@ #define PR_Unlock(x) (void)0 #endif +// Logging of debug output +#define FORCE_PR_LOG /* Allow logging in the release build */ +extern PRLogModuleInfo *nsComponentManagerLog; + PRUnichar widestrFormat[] = { PRUnichar('%'),PRUnichar('s'),PRUnichar(0)}; /*-------------------------------- nsRegistry ---------------------------------- @@ -416,9 +422,62 @@ NS_IMETHODIMP nsRegistry::Open( const char *regFile ) { | Takes a registry id and maps that to a file name for opening. We first check | | to see if a registry file is already open and close it if so. | ------------------------------------------------------------------------------*/ -NS_IMETHODIMP nsRegistry::OpenWellKnownRegistry( nsWellKnownRegistry regid ) { +NS_IMETHODIMP nsRegistry::OpenWellKnownRegistry( nsWellKnownRegistry regid ) +{ REGERR err = REGERR_OK; + + #ifdef XP_UNIX + // Create ~/.mozilla as that is the default place for the registry file + + /* The default registry on the unix system is $HOME/.mozilla/registry per + * vr_findGlobalRegName(). vr_findRegFile() will create the registry file + * if it doesn't exist. But it wont create directories. + * + * Hence we need to create the directory if it doesn't exist already. + * + * Why create it here as opposed to the app ? + * ------------------------------------------ + * The app cannot create the directory in main() as most of the registry + * and initialization happens due to use of static variables. + * And we dont want to be dependent on the order in which + * these static stuff happen. + * + * Permission for the $HOME/.mozilla will be Read,Write,Execute + * for user only. Nothing to group and others. + */ + char *home = getenv("HOME"); + if (home != NULL) + { + char dotMozillaDir[1024]; + PR_snprintf(dotMozillaDir, sizeof(dotMozillaDir), + "%s/" NS_MOZILLA_DIR_NAME, home); + if (PR_Access(dotMozillaDir, PR_ACCESS_EXISTS) != PR_SUCCESS) + { + PR_MkDir(dotMozillaDir, NS_MOZILLA_DIR_PERMISSION); + PR_LOG(nsComponentManagerLog, PR_LOG_ALWAYS, + ("nsComponentManager: Creating Directory %s", dotMozillaDir)); + } + } +#endif /* XP_UNIX */ + +#ifdef XP_BEOS + BPath p; + const char *settings = "/boot/home/config/settings"; + if(find_directory(B_USER_SETTINGS_DIRECTORY, &p) == B_OK) + settings = p.Path(); + char settingsMozillaDir[1024]; + PR_snprintf(settingsMozillaDir, sizeof(settingsMozillaDir), + "%s/" NS_MOZILLA_DIR_NAME, settings); + if (PR_Access(settingsMozillaDir, PR_ACCESS_EXISTS) != PR_SUCCESS) { + PR_MkDir(settingsMozillaDir, NS_MOZILLA_DIR_PERMISSION); + printf("nsComponentManager: Creating Directory %s\n", settingsMozillaDir); + PR_LOG(nsComponentManagerLog, PR_LOG_ALWAYS, + ("nsComponentManager: Creating Directory %s", settingsMozillaDir)); + } +#endif + + if (mCurRegID != nsIRegistry::None && mCurRegID != regid) { // Cant open another registry without closing explictly. @@ -440,6 +499,8 @@ NS_IMETHODIMP nsRegistry::OpenWellKnownRegistry( nsWellKnownRegistry regid ) { switch ( (nsWellKnownRegistry) regid ) { case ApplicationComponentRegistry: { + // can't use NS_GetSpecialDirectory here. Called before service manager is initialized. + nsCOMPtr directoryService; rv = nsDirectoryService::Create(nsnull, NS_GET_IID(nsIProperties), @@ -447,7 +508,7 @@ NS_IMETHODIMP nsRegistry::OpenWellKnownRegistry( nsWellKnownRegistry regid ) { if (NS_FAILED(rv)) return rv; directoryService->Get(NS_XPCOM_COMPONENT_REGISTRY_FILE, NS_GET_IID(nsIFile), getter_AddRefs(registryLocation)); - + if (registryLocation) { foundReg = PR_TRUE; @@ -462,8 +523,25 @@ NS_IMETHODIMP nsRegistry::OpenWellKnownRegistry( nsWellKnownRegistry regid ) { break; case ApplicationRegistry: { - foundReg = PR_TRUE; - // NULL regFile will open the right one for this case. + // can't use NS_GetSpecialDirectory here. Called before service manager is initialized. + + nsCOMPtr directoryService; + rv = nsDirectoryService::Create(nsnull, + NS_GET_IID(nsIProperties), + getter_AddRefs(directoryService)); + if (NS_FAILED(rv)) return rv; + directoryService->Get(NS_XPCOM_APPLICATION_REGISTRY_FILE, NS_GET_IID(nsIFile), + getter_AddRefs(registryLocation)); + + if (registryLocation) + { + foundReg = PR_TRUE; + registryLocation->GetPath(®File); // dougt fix... + // dveditz needs to fix his registry so that I can pass an + // nsIFile interface and not hack + if (!regFile) + return NS_ERROR_OUT_OF_MEMORY; + } } break; diff --git a/mozilla/xpcom/io/nsDirectoryService.cpp b/mozilla/xpcom/io/nsDirectoryService.cpp index 5a99afa7d71..0e3c274623f 100644 --- a/mozilla/xpcom/io/nsDirectoryService.cpp +++ b/mozilla/xpcom/io/nsDirectoryService.cpp @@ -58,7 +58,6 @@ #include "nsSpecialSystemDirectory.h" - #ifdef XP_MAC #define COMPONENT_REGISTRY_NAME "Component Registry" #define COMPONENT_DIRECTORY "Components" @@ -67,16 +66,41 @@ #define COMPONENT_DIRECTORY "components" #endif +#ifdef XP_MAC +#define APP_REGISTRY_NAME "Application Registry" +#elif defined(XP_PC) +#define APP_REGISTRY_NAME "registry.dat" +#else +#define APP_REGISTRY_NAME "appreg" +#endif +// define home directory +#ifdef XP_PC +#define HOME_DIR NS_WIN_HOME_DIR +#elif defined (XP_MAC) +#define HOME_DIR NS_MAC_HOME_DIR +#elif defined (XP_UNIX) +#define HOME_DIR NS_UNIX_HOME_DIR +#endif +// define default product directory +#if defined(XP_PC) || defined(XP_MAC) +#define DEFAULT_PRODUCT_DIR "Mozilla" +#elif defined (XP_UNIX) +#define DEFAULT_PRODUCT_DIR ".mozilla" +#endif //---------------------------------------------------------------------------------------- -static nsresult GetCurrentProcessDirectory(nsILocalFile** aFile) +nsresult +nsDirectoryService::GetCurrentProcessDirectory(nsILocalFile** aFile) //---------------------------------------------------------------------------------------- { // Set the component registry location: - nsresult rv; + if (!mService) + return NS_ERROR_FAILURE; + nsresult rv; + nsCOMPtr dirService; rv = nsDirectoryService::Create(nsnull, NS_GET_IID(nsIProperties), @@ -234,6 +258,8 @@ static nsresult GetCurrentProcessDirectory(nsILocalFile** aFile) nsIAtom* nsDirectoryService::sCurrentProcess = nsnull; +nsIAtom* nsDirectoryService::sAppRegistryDirectory = nsnull; +nsIAtom* nsDirectoryService::sAppRegistry = nsnull; nsIAtom* nsDirectoryService::sComponentRegistry = nsnull; nsIAtom* nsDirectoryService::sComponentDirectory = nsnull; nsIAtom* nsDirectoryService::sOS_DriveDirectory = nsnull; @@ -253,6 +279,7 @@ nsIAtom* nsDirectoryService::sFontsDirectory = nsnull; nsIAtom* nsDirectoryService::sPreferencesDirectory = nsnull; nsIAtom* nsDirectoryService::sDocumentsDirectory = nsnull; nsIAtom* nsDirectoryService::sInternetSearchDirectory = nsnull; +nsIAtom* nsDirectoryService::sHomeDirectory = nsnull; #elif defined (XP_OS2) nsIAtom* nsDirectoryService::sSystemDirectory = nsnull; nsIAtom* nsDirectoryService::sOS2Directory = nsnull; @@ -307,30 +334,17 @@ NS_METHOD nsDirectoryService::Create(nsISupports *outer, REFNSIID aIID, void **aResult) { NS_ENSURE_ARG_POINTER(aResult); - nsresult rv; - if (mService == nsnull) { mService = new nsDirectoryService(); if (mService == NULL) return NS_ERROR_OUT_OF_MEMORY; - - // use this to temporarily hold a reference to mService: - nsCOMPtr serv = mService; - - rv = mService->Init(); - if (NS_FAILED(rv)) return rv; - rv = mService->QueryInterface(aIID, aResult); } - else - { - rv = mService->QueryInterface(aIID, aResult); - } - return rv; + return mService->QueryInterface(aIID, aResult); } nsresult -nsDirectoryService::Init() +nsDirectoryService::Init(const char *productName) { nsresult rv; mHashtable = new nsSupportsHashtable(256, PR_TRUE); @@ -340,10 +354,13 @@ nsDirectoryService::Init() rv = NS_NewISupportsArray(getter_AddRefs(mProviders)); if (NS_FAILED(rv)) return rv; - + mProductName = productName; + nsDirectoryService::sCurrentProcess = NS_NewAtom(NS_XPCOM_CURRENT_PROCESS_DIR); nsDirectoryService::sComponentRegistry = NS_NewAtom(NS_XPCOM_COMPONENT_REGISTRY_FILE); nsDirectoryService::sComponentDirectory = NS_NewAtom(NS_XPCOM_COMPONENT_DIR); + nsDirectoryService::sAppRegistryDirectory = NS_NewAtom(NS_XPCOM_APPLICATION_REGISTRY_DIR); + nsDirectoryService::sAppRegistry = NS_NewAtom(NS_XPCOM_APPLICATION_REGISTRY_FILE); nsDirectoryService::sOS_DriveDirectory = NS_NewAtom(NS_OS_DRIVE_DIR); nsDirectoryService::sOS_TemporaryDirectory = NS_NewAtom(NS_OS_TEMP_DIR); @@ -362,6 +379,7 @@ nsDirectoryService::Init() nsDirectoryService::sPreferencesDirectory = NS_NewAtom(NS_MAC_PREFS_DIR); nsDirectoryService::sDocumentsDirectory = NS_NewAtom(NS_MAC_DOCUMENTS_DIR); nsDirectoryService::sInternetSearchDirectory = NS_NewAtom(NS_MAC_INTERNET_SEARCH_DIR); + nsDirectoryService::sHomeDirectory = NS_NewAtom(NS_MAC_HOME_DIR); #elif defined (XP_OS2) nsDirectoryService::sSystemDirectory = NS_NewAtom(NS_OS_SYSTEM_DIR); nsDirectoryService::sOS2Directory = NS_NewAtom(NS_OS2_DIR); @@ -404,10 +422,6 @@ nsDirectoryService::Init() nsDirectoryService::sDesktopDirectory = NS_NewAtom(NS_BEOS_DESKTOP_DIR); #endif - rv = RegisterProvider(NS_STATIC_CAST(nsIDirectoryServiceProvider*, this)); - // don't let RegisterProvider keep a reference to ourself, otherwise - // we'll never be freed: - NS_RELEASE_THIS(); return rv; } @@ -421,20 +435,11 @@ nsDirectoryService::ReleaseValues(nsHashKey* key, void* data, void* closure) nsDirectoryService::~nsDirectoryService() { - nsresult rv; - // Now we need to carefully remove the weak reference to ourself that we added - // when Init called RegisterProvider. Otherwise, we'll crash trying to delete - // this nsDirectoryService twice: - mRefCnt = 99999; - nsIDirectoryService* serv = NS_STATIC_CAST(nsIDirectoryService*, this); - nsISupports* supports = NS_STATIC_CAST(nsISupports*, serv); - - rv = mProviders->RemoveElement(supports); - NS_ASSERTION(NS_SUCCEEDED(rv), "RemoveElement failed"); - delete mHashtable; NS_IF_RELEASE(nsDirectoryService::sCurrentProcess); + NS_IF_RELEASE(nsDirectoryService::sAppRegistryDirectory); + NS_IF_RELEASE(nsDirectoryService::sAppRegistry); NS_IF_RELEASE(nsDirectoryService::sComponentRegistry); NS_IF_RELEASE(nsDirectoryService::sComponentDirectory); NS_IF_RELEASE(nsDirectoryService::sOS_DriveDirectory); @@ -454,6 +459,7 @@ nsDirectoryService::~nsDirectoryService() NS_IF_RELEASE(nsDirectoryService::sPreferencesDirectory); NS_IF_RELEASE(nsDirectoryService::sDocumentsDirectory); NS_IF_RELEASE(nsDirectoryService::sInternetSearchDirectory); + NS_IF_RELEASE(nsDirectoryService::sHomeDirectory); #elif defined (XP_OS2) NS_IF_RELEASE(nsDirectoryService::sSystemDirectory); NS_IF_RELEASE(nsDirectoryService::sOS2Directory); @@ -525,7 +531,7 @@ typedef struct FileData { const char* property; nsIFile* file; - PRBool persistant; + PRBool persistent; } FileData; @@ -536,7 +542,7 @@ static PRBool FindProviderFile(nsISupports* aElement, void *aData) return PR_FALSE; FileData* fileData = (FileData*)aData; - prov->GetFile(fileData->property, &fileData->persistant, &(fileData->file) ); + prov->GetFile(fileData->property, &fileData->persistent, &(fileData->file) ); if (fileData->file) return PR_FALSE; @@ -567,20 +573,31 @@ nsDirectoryService::Get(const char* prop, const nsIID & uuid, void* *result) FileData fileData; fileData.property = prop; fileData.file = nsnull; - fileData.persistant = PR_TRUE; + fileData.persistent = PR_TRUE; mProviders->EnumerateForwards(FindProviderFile, &fileData); - if (fileData.file) { - if (fileData.persistant) + if (fileData.persistent) { Set(prop, NS_STATIC_CAST(nsIFile*, fileData.file)); } nsresult rv = (fileData.file)->QueryInterface(uuid, result); NS_RELEASE(fileData.file); // addref occurs in FindProviderFile() return rv; - } + } + + FindProviderFile(NS_STATIC_CAST(nsIDirectoryServiceProvider*, this), &fileData); + if (fileData.file) + { + if (fileData.persistent) + { + Set(prop, NS_STATIC_CAST(nsIFile*, fileData.file)); + } + nsresult rv = (fileData.file)->QueryInterface(uuid, result); + NS_RELEASE(fileData.file); // addref occurs in FindProviderFile() + return rv; + } } return NS_ERROR_FAILURE; @@ -647,13 +664,13 @@ nsDirectoryService::RegisterProvider(nsIDirectoryServiceProvider *prov) // your application. NS_IMETHODIMP -nsDirectoryService::GetFile(const char *prop, PRBool *persistant, nsIFile **_retval) +nsDirectoryService::GetFile(const char *prop, PRBool *persistent, nsIFile **_retval) { nsCOMPtr localFile; nsresult rv = NS_ERROR_FAILURE; *_retval = nsnull; - *persistant = PR_TRUE; + *persistent = PR_TRUE; nsIAtom* inAtom = NS_NewAtom(prop); @@ -663,6 +680,62 @@ nsDirectoryService::GetFile(const char *prop, PRBool *persistant, nsIFile **_ret { rv = GetCurrentProcessDirectory(getter_AddRefs(localFile)); } + else if (inAtom == nsDirectoryService::sAppRegistryDirectory) + { + nsCOMPtr homeDir; + GetFile(HOME_DIR, persistent, getter_AddRefs(homeDir)); + +#ifdef XP_PC + PRBool dirExists = PR_FALSE; + if (homeDir) + { + homeDir->Exists(&dirExists); + if (!dirExists) + GetFile(NS_WIN_WINDOWS_DIR,persistent, getter_AddRefs(homeDir)); + } +#endif + if (homeDir) + { + localFile = do_QueryInterface(homeDir); + + nsCString productName = mProductName; + + if (!(productName.mLength)) + productName = DEFAULT_PRODUCT_DIR; + + nsCString temp = productName; + if (localFile) + rv = localFile->Append(temp); + + if (NS_SUCCEEDED(rv)) + { + + // Create the new directory + PRBool newDirExists = PR_FALSE; + localFile->Exists(&newDirExists); + + if (!newDirExists) + { + rv = localFile->Create(nsIFile::DIRECTORY_TYPE, 0755); + } + } + } + else + rv = NS_ERROR_FAILURE; + } + else if (inAtom == nsDirectoryService::sAppRegistry) + { + nsCOMPtr registryDir; + GetFile(NS_XPCOM_APPLICATION_REGISTRY_DIR, persistent, getter_AddRefs(registryDir)); + + if (registryDir) + { + localFile = do_QueryInterface(registryDir); + rv = localFile->Append(APP_REGISTRY_NAME); + } + else + rv = NS_ERROR_FAILURE; + } else if (inAtom == nsDirectoryService::sComponentRegistry) { rv = GetCurrentProcessDirectory(getter_AddRefs(localFile)); @@ -707,6 +780,11 @@ nsDirectoryService::GetFile(const char *prop, PRBool *persistant, nsIFile **_ret nsSpecialSystemDirectory fileSpec(nsSpecialSystemDirectory::Mac_DesktopDirectory); rv = NS_FileSpecToIFile(&fileSpec, getter_AddRefs(localFile)); } + else if (inAtom == nsDirectoryService::sHomeDirectory) + { + nsSpecialSystemDirectory fileSpec(nsSpecialSystemDirectory::Mac_DocumentsDirectory); + rv = NS_FileSpecToIFile(&fileSpec, getter_AddRefs(localFile)); + } else if (inAtom == nsDirectoryService::sTrashDirectory) { nsSpecialSystemDirectory fileSpec(nsSpecialSystemDirectory::Mac_TrashDirectory); diff --git a/mozilla/xpcom/io/nsDirectoryService.h b/mozilla/xpcom/io/nsDirectoryService.h index 376b5189005..9bee600c95f 100644 --- a/mozilla/xpcom/io/nsDirectoryService.h +++ b/mozilla/xpcom/io/nsDirectoryService.h @@ -26,8 +26,11 @@ #include "nsIDirectoryService.h" #include "nsHashtable.h" -#include "nsIFile.h" +#include "nsILocalFile.h" #include "nsISupportsArray.h" +#include "nsXPIDLString.h" + + class nsDirectoryService : public nsIDirectoryService, public nsIProperties, public nsIDirectoryServiceProvider { public: @@ -52,12 +55,18 @@ class nsDirectoryService : public nsIDirectoryService, public nsIProperties, pub Create(nsISupports *aOuter, REFNSIID aIID, void **aResult); private: + nsresult GetCurrentProcessDirectory(nsILocalFile** aFile); + static nsDirectoryService* mService; static PRBool PR_CALLBACK ReleaseValues(nsHashKey* key, void* data, void* closure); nsSupportsHashtable* mHashtable; nsCOMPtr mProviders; + nsCString mProductName; + static nsIAtom *sCurrentProcess; + static nsIAtom *sAppRegistryDirectory; + static nsIAtom *sAppRegistry; static nsIAtom *sComponentRegistry; static nsIAtom *sComponentDirectory; static nsIAtom *sOS_DriveDirectory; @@ -77,6 +86,7 @@ private: static nsIAtom *sPreferencesDirectory; static nsIAtom *sDocumentsDirectory; static nsIAtom *sInternetSearchDirectory; + static nsIAtom *sHomeDirectory; #elif defined (XP_OS2) static nsIAtom *sSystemDirectory; static nsIAtom *sOS2Directory; diff --git a/mozilla/xpcom/io/nsDirectoryServiceDefs.h b/mozilla/xpcom/io/nsDirectoryServiceDefs.h index c9ea7cb3c1d..5406273f5a5 100755 --- a/mozilla/xpcom/io/nsDirectoryServiceDefs.h +++ b/mozilla/xpcom/io/nsDirectoryServiceDefs.h @@ -40,6 +40,8 @@ #define NS_XPCOM_CURRENT_PROCESS_DIR "CurProcD" #define NS_XPCOM_COMPONENT_REGISTRY_FILE "ComRegF" #define NS_XPCOM_COMPONENT_DIR "ComsD" +#define NS_XPCOM_APPLICATION_REGISTRY_FILE "AppRegF" +#define NS_XPCOM_APPLICATION_REGISTRY_DIR "AppRegD" #define NS_OS_DRIVE_DIR "DrvD" #define NS_OS_TEMP_DIR "TmpD" @@ -62,6 +64,7 @@ #define NS_MAC_PREFS_DIR "Prfs" #define NS_MAC_DOCUMENTS_DIR "Docs" #define NS_MAC_INTERNET_SEARCH_DIR "ISrch" + #define NS_MAC_HOME_DIR "Home" #elif defined (XP_OS2) #define NS_OS2_DIR "0S2Dir" #define NS_OS2_DESKTOP_DIR "Desk" diff --git a/mozilla/xpcom/io/nsIDirectoryService.idl b/mozilla/xpcom/io/nsIDirectoryService.idl index 6a7e8df1dfa..d68ad6ab741 100644 --- a/mozilla/xpcom/io/nsIDirectoryService.idl +++ b/mozilla/xpcom/io/nsIDirectoryService.idl @@ -32,6 +32,7 @@ interface nsIDirectoryServiceProvider: nsISupports [scriptable, uuid(57a66a60-d43a-11d3-8cc2-00609792278c)] interface nsIDirectoryService: nsISupports { + void init(in string productName); void registerProvider(in nsIDirectoryServiceProvider prov); }; diff --git a/mozilla/xpcom/io/nsSpecialSystemDirectory.cpp b/mozilla/xpcom/io/nsSpecialSystemDirectory.cpp index dbc7c30094e..24aa174a3ad 100644 --- a/mozilla/xpcom/io/nsSpecialSystemDirectory.cpp +++ b/mozilla/xpcom/io/nsSpecialSystemDirectory.cpp @@ -585,6 +585,20 @@ void nsSpecialSystemDirectory::operator = (SystemDirectories aSystemSystemDirect case Win_HomeDirectory: { char path[_MAX_PATH]; + if (GetEnvironmentVariable(TEXT("HOME"), path, _MAX_PATH) >= 0) + { + PRInt32 len = PL_strlen(path); + // Need enough space to add the trailing backslash + if (len > _MAX_PATH - 2) + break; + + path[len] = '\\'; + path[len+1] = '\0'; + + *this = MakeUpperCase(path); + break; + } + if (GetEnvironmentVariable(TEXT("HOMEDRIVE"), path, _MAX_PATH) >= 0) { char temp[_MAX_PATH]; @@ -599,10 +613,10 @@ void nsSpecialSystemDirectory::operator = (SystemDirectories aSystemSystemDirect path[len] = '\\'; path[len+1] = '\0'; + + *this = MakeUpperCase(path); + break; } - - *this = MakeUpperCase(path); - break; } case Win_Desktop: {