VirtualBox

source: vbox/trunk/src/libs/xpcom18a4/xpcom/io/nsDirectoryService.cpp@ 101866

Last change on this file since 101866 was 101866, checked in by vboxsync, 13 months ago

libs/xpcom: Cleanup nsDirectoryService.cpp and SpecialSystemDirectory.{cpp,h} to include stuff we actually care for, bugref:10545

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 29.7 KB
Line 
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 *
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
9 *
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
14 *
15 * The Original Code is mozilla.org code.
16 *
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
21 *
22 * Contributor(s):
23 * IBM Corp.
24 *
25 * Alternatively, the contents of this file may be used under the terms of
26 * either of the GNU General Public License Version 2 or later (the "GPL"),
27 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 * in which case the provisions of the GPL or the LGPL are applicable instead
29 * of those above. If you wish to allow use of your version of this file only
30 * under the terms of either the GPL or the LGPL, and not to allow others to
31 * use your version of this file under the terms of the MPL, indicate your
32 * decision by deleting the provisions above and replace them with the notice
33 * and other provisions required by the GPL or the LGPL. If you do not delete
34 * the provisions above, a recipient may use your version of this file under
35 * the terms of any one of the MPL, the GPL or the LGPL.
36 *
37 * ***** END LICENSE BLOCK ***** */
38
39#include "nsCOMPtr.h"
40#include "nsDirectoryService.h"
41#include "nsDirectoryServiceDefs.h"
42#include "nsLocalFile.h"
43#include "nsDebug.h"
44#include "nsStaticAtom.h"
45
46#if defined(XP_UNIX) || defined(XP_MACOSX)
47#include <unistd.h>
48#include <stdlib.h>
49#include <sys/param.h>
50#include <dlfcn.h>
51#include "prenv.h"
52#ifdef XP_MACOSX
53#include <CoreServices/CoreServices.h>
54#include <Folders.h>
55#include <Files.h>
56# ifndef VBOX_WITH_NEWER_OSX_SDK
57# include <Memory.h>
58# endif
59#include <Processes.h>
60#include <Gestalt.h>
61#include <CFURL.h>
62#include <InternetConfig.h>
63#endif
64#endif
65
66#include "SpecialSystemDirectory.h"
67#include "nsAppFileLocationProvider.h"
68
69#define COMPONENT_REGISTRY_NAME NS_LITERAL_CSTRING("compreg.dat")
70#define COMPONENT_DIRECTORY NS_LITERAL_CSTRING("components")
71
72#define XPTI_REGISTRY_NAME NS_LITERAL_CSTRING("xpti.dat")
73
74// define home directory
75#if defined (XP_MACOSX)
76#define HOME_DIR NS_OSX_HOME_DIR
77#elif defined (XP_UNIX)
78#define HOME_DIR NS_UNIX_HOME_DIR
79#endif
80
81//----------------------------------------------------------------------------------------
82nsresult
83nsDirectoryService::GetCurrentProcessDirectory(nsILocalFile** aFile)
84//----------------------------------------------------------------------------------------
85{
86 NS_ENSURE_ARG_POINTER(aFile);
87 *aFile = nsnull;
88
89 // Set the component registry location:
90 if (!mService)
91 return NS_ERROR_FAILURE;
92
93 nsresult rv;
94
95 nsCOMPtr<nsIProperties> dirService;
96 rv = nsDirectoryService::Create(nsnull,
97 NS_GET_IID(nsIProperties),
98 getter_AddRefs(dirService)); // needs to be around for life of product
99
100 if (dirService)
101 {
102 nsCOMPtr <nsILocalFile> aLocalFile;
103 dirService->Get(NS_XPCOM_INIT_CURRENT_PROCESS_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(aLocalFile));
104 if (aLocalFile)
105 {
106 *aFile = aLocalFile;
107 NS_ADDREF(*aFile);
108 return NS_OK;
109 }
110 }
111
112 nsLocalFile* localFile = new nsLocalFile;
113
114 if (localFile == nsnull)
115 return NS_ERROR_OUT_OF_MEMORY;
116 NS_ADDREF(localFile);
117
118
119
120#if defined(XP_MACOSX)
121# ifdef MOZ_DEFAULT_VBOX_XPCOM_HOME
122 rv = localFile->InitWithNativePath(nsDependentCString(MOZ_DEFAULT_VBOX_XPCOM_HOME));
123 if (NS_SUCCEEDED(rv))
124 *aFile = localFile;
125# else
126 // Works even if we're not bundled.
127 CFBundleRef appBundle = CFBundleGetMainBundle();
128 if (appBundle != nsnull)
129 {
130 CFURLRef bundleURL = CFBundleCopyExecutableURL(appBundle);
131 if (bundleURL != nsnull)
132 {
133 CFURLRef parentURL = CFURLCreateCopyDeletingLastPathComponent(kCFAllocatorDefault, bundleURL);
134 if (parentURL)
135 {
136 // Pass PR_TRUE for the "resolveAgainstBase" arg to CFURLGetFileSystemRepresentation.
137 // This will resolve the relative portion of the CFURL against it base, giving a full
138 // path, which CFURLCopyFileSystemPath doesn't do.
139 char buffer[PATH_MAX];
140 if (CFURLGetFileSystemRepresentation(parentURL, PR_TRUE, (UInt8 *)buffer, sizeof(buffer)))
141 {
142 rv = localFile->InitWithNativePath(nsDependentCString(buffer));
143 if (NS_SUCCEEDED(rv))
144 *aFile = localFile;
145 }
146 CFRelease(parentURL);
147 }
148 CFRelease(bundleURL);
149 }
150 }
151#endif
152
153 NS_ASSERTION(*aFile, "nsDirectoryService - Could not determine CurrentProcessDir.\n");
154 if (*aFile)
155 return NS_OK;
156
157#elif defined(XP_UNIX)
158
159 // In the absence of a good way to get the executable directory let
160 // us try this for unix:
161 // - if VBOX_XPCOM_HOME is defined, that is it
162 // - else give the current directory
163 char buf[MAXPATHLEN];
164
165 // The MOZ_DEFAULT_VBOX_XPCOM_HOME variable can be set at configure time with
166 // a --with-default-mozilla-five-home=foo autoconf flag.
167 //
168 // The idea here is to allow for builds that have a default VBOX_XPCOM_HOME
169 // regardless of the environment. This makes it easier to write apps that
170 // embed mozilla without having to worry about setting up the environment
171 //
172 // We do this py putenv()ing the default value into the environment. Note that
173 // we only do this if it is not already set.
174#ifdef MOZ_DEFAULT_VBOX_XPCOM_HOME
175 if (PR_GetEnv("VBOX_XPCOM_HOME") == nsnull)
176 PR_SetEnv("VBOX_XPCOM_HOME=" MOZ_DEFAULT_VBOX_XPCOM_HOME);
177#endif
178
179 char *moz5 = PR_GetEnv("VBOX_XPCOM_HOME");
180
181 if (moz5)
182 {
183 if (realpath(moz5, buf)) {
184 localFile->InitWithNativePath(nsDependentCString(buf));
185 *aFile = localFile;
186 return NS_OK;
187 }
188 }
189#if defined(DEBUG)
190 static PRBool firstWarning = PR_TRUE;
191
192 if(!moz5 && firstWarning) {
193 // Warn that VBOX_XPCOM_HOME not set, once.
194 printf("Warning: VBOX_XPCOM_HOME not set.\n");
195 firstWarning = PR_FALSE;
196 }
197#endif /* DEBUG */
198
199 // Fall back to current directory.
200 if (getcwd(buf, sizeof(buf)))
201 {
202 localFile->InitWithNativePath(nsDependentCString(buf));
203 *aFile = localFile;
204 return NS_OK;
205 }
206
207#endif
208
209 NS_RELEASE(localFile);
210
211 NS_ERROR("unable to get current process directory");
212 return NS_ERROR_FAILURE;
213} // GetCurrentProcessDirectory()
214
215
216nsIAtom* nsDirectoryService::sCurrentProcess = nsnull;
217nsIAtom* nsDirectoryService::sComponentRegistry = nsnull;
218nsIAtom* nsDirectoryService::sXPTIRegistry = nsnull;
219nsIAtom* nsDirectoryService::sComponentDirectory = nsnull;
220nsIAtom* nsDirectoryService::sGRE_Directory = nsnull;
221nsIAtom* nsDirectoryService::sGRE_ComponentDirectory = nsnull;
222nsIAtom* nsDirectoryService::sOS_DriveDirectory = nsnull;
223nsIAtom* nsDirectoryService::sOS_TemporaryDirectory = nsnull;
224nsIAtom* nsDirectoryService::sOS_CurrentProcessDirectory = nsnull;
225nsIAtom* nsDirectoryService::sOS_CurrentWorkingDirectory = nsnull;
226#if defined (XP_MACOSX)
227nsIAtom* nsDirectoryService::sDirectory = nsnull;
228nsIAtom* nsDirectoryService::sDesktopDirectory = nsnull;
229nsIAtom* nsDirectoryService::sTrashDirectory = nsnull;
230nsIAtom* nsDirectoryService::sStartupDirectory = nsnull;
231nsIAtom* nsDirectoryService::sShutdownDirectory = nsnull;
232nsIAtom* nsDirectoryService::sAppleMenuDirectory = nsnull;
233nsIAtom* nsDirectoryService::sControlPanelDirectory = nsnull;
234nsIAtom* nsDirectoryService::sExtensionDirectory = nsnull;
235nsIAtom* nsDirectoryService::sFontsDirectory = nsnull;
236nsIAtom* nsDirectoryService::sPreferencesDirectory = nsnull;
237nsIAtom* nsDirectoryService::sDocumentsDirectory = nsnull;
238nsIAtom* nsDirectoryService::sInternetSearchDirectory = nsnull;
239nsIAtom* nsDirectoryService::sUserLibDirectory = nsnull;
240nsIAtom* nsDirectoryService::sHomeDirectory = nsnull;
241nsIAtom* nsDirectoryService::sDefaultDownloadDirectory = nsnull;
242nsIAtom* nsDirectoryService::sUserDesktopDirectory = nsnull;
243nsIAtom* nsDirectoryService::sLocalDesktopDirectory = nsnull;
244nsIAtom* nsDirectoryService::sUserApplicationsDirectory = nsnull;
245nsIAtom* nsDirectoryService::sLocalApplicationsDirectory = nsnull;
246nsIAtom* nsDirectoryService::sUserDocumentsDirectory = nsnull;
247nsIAtom* nsDirectoryService::sLocalDocumentsDirectory = nsnull;
248nsIAtom* nsDirectoryService::sUserInternetPlugInDirectory = nsnull;
249nsIAtom* nsDirectoryService::sLocalInternetPlugInDirectory = nsnull;
250nsIAtom* nsDirectoryService::sUserFrameworksDirectory = nsnull;
251nsIAtom* nsDirectoryService::sLocalFrameworksDirectory = nsnull;
252nsIAtom* nsDirectoryService::sUserPreferencesDirectory = nsnull;
253nsIAtom* nsDirectoryService::sLocalPreferencesDirectory = nsnull;
254nsIAtom* nsDirectoryService::sPictureDocumentsDirectory = nsnull;
255nsIAtom* nsDirectoryService::sMovieDocumentsDirectory = nsnull;
256nsIAtom* nsDirectoryService::sMusicDocumentsDirectory = nsnull;
257nsIAtom* nsDirectoryService::sInternetSitesDirectory = nsnull;
258#elif defined (XP_UNIX)
259nsIAtom* nsDirectoryService::sLocalDirectory = nsnull;
260nsIAtom* nsDirectoryService::sLibDirectory = nsnull;
261nsIAtom* nsDirectoryService::sHomeDirectory = nsnull;
262#endif
263
264
265nsDirectoryService* nsDirectoryService::mService = nsnull;
266
267nsDirectoryService::nsDirectoryService() :
268 mHashtable(256, PR_TRUE)
269{
270}
271
272NS_METHOD
273nsDirectoryService::Create(nsISupports *outer, REFNSIID aIID, void **aResult)
274{
275 NS_ENSURE_ARG_POINTER(aResult);
276 if (!mService)
277 {
278 mService = new nsDirectoryService();
279 if (!mService)
280 return NS_ERROR_OUT_OF_MEMORY;
281 }
282 return mService->QueryInterface(aIID, aResult);
283}
284
285static const nsStaticAtom directory_atoms[] = {
286 { NS_XPCOM_CURRENT_PROCESS_DIR, &nsDirectoryService::sCurrentProcess },
287 { NS_XPCOM_COMPONENT_REGISTRY_FILE, &nsDirectoryService::sComponentRegistry },
288 { NS_XPCOM_COMPONENT_DIR, &nsDirectoryService::sComponentDirectory },
289 { NS_XPCOM_XPTI_REGISTRY_FILE, &nsDirectoryService::sXPTIRegistry },
290 { NS_GRE_DIR, &nsDirectoryService::sGRE_Directory },
291 { NS_GRE_COMPONENT_DIR, &nsDirectoryService::sGRE_ComponentDirectory },
292 { NS_OS_DRIVE_DIR, &nsDirectoryService::sOS_DriveDirectory },
293 { NS_OS_TEMP_DIR, &nsDirectoryService::sOS_TemporaryDirectory },
294 { NS_OS_CURRENT_PROCESS_DIR, &nsDirectoryService::sOS_CurrentProcessDirectory },
295 { NS_OS_CURRENT_WORKING_DIR, &nsDirectoryService::sOS_CurrentWorkingDirectory },
296 { NS_XPCOM_INIT_CURRENT_PROCESS_DIR, nsnull },
297#if defined (XP_MACOSX)
298 { NS_OS_SYSTEM_DIR, &nsDirectoryService::sDirectory },
299 { NS_MAC_DESKTOP_DIR, &nsDirectoryService::sDesktopDirectory },
300 { NS_MAC_TRASH_DIR, &nsDirectoryService::sTrashDirectory },
301 { NS_MAC_STARTUP_DIR, &nsDirectoryService::sStartupDirectory },
302 { NS_MAC_SHUTDOWN_DIR, &nsDirectoryService::sShutdownDirectory },
303 { NS_MAC_APPLE_MENU_DIR, &nsDirectoryService::sAppleMenuDirectory },
304 { NS_MAC_CONTROL_PANELS_DIR, &nsDirectoryService::sControlPanelDirectory },
305 { NS_MAC_EXTENSIONS_DIR, &nsDirectoryService::sExtensionDirectory },
306 { NS_MAC_FONTS_DIR, &nsDirectoryService::sFontsDirectory },
307 { NS_MAC_PREFS_DIR, &nsDirectoryService::sPreferencesDirectory },
308 { NS_MAC_DOCUMENTS_DIR, &nsDirectoryService::sDocumentsDirectory },
309 { NS_MAC_INTERNET_SEARCH_DIR, &nsDirectoryService::sInternetSearchDirectory },
310 { NS_MAC_USER_LIB_DIR, &nsDirectoryService::sUserLibDirectory },
311 { NS_OSX_HOME_DIR, &nsDirectoryService::sHomeDirectory },
312 { NS_OSX_DEFAULT_DOWNLOAD_DIR, &nsDirectoryService::sDefaultDownloadDirectory },
313 { NS_OSX_USER_DESKTOP_DIR, &nsDirectoryService::sUserDesktopDirectory },
314 { NS_OSX_LOCAL_DESKTOP_DIR, &nsDirectoryService::sLocalDesktopDirectory },
315 { NS_OSX_USER_APPLICATIONS_DIR, &nsDirectoryService::sUserApplicationsDirectory },
316 { NS_OSX_LOCAL_APPLICATIONS_DIR, &nsDirectoryService::sLocalApplicationsDirectory },
317 { NS_OSX_USER_DOCUMENTS_DIR, &nsDirectoryService::sUserDocumentsDirectory },
318 { NS_OSX_LOCAL_DOCUMENTS_DIR, &nsDirectoryService::sLocalDocumentsDirectory },
319 { NS_OSX_USER_INTERNET_PLUGIN_DIR, &nsDirectoryService::sUserInternetPlugInDirectory },
320 { NS_OSX_LOCAL_INTERNET_PLUGIN_DIR, &nsDirectoryService::sLocalInternetPlugInDirectory },
321 { NS_OSX_USER_FRAMEWORKS_DIR, &nsDirectoryService::sUserFrameworksDirectory },
322 { NS_OSX_LOCAL_FRAMEWORKS_DIR, &nsDirectoryService::sLocalFrameworksDirectory },
323 { NS_OSX_USER_PREFERENCES_DIR, &nsDirectoryService::sUserPreferencesDirectory },
324 { NS_OSX_LOCAL_PREFERENCES_DIR, &nsDirectoryService::sLocalPreferencesDirectory },
325 { NS_OSX_PICTURE_DOCUMENTS_DIR, &nsDirectoryService::sPictureDocumentsDirectory },
326 { NS_OSX_MOVIE_DOCUMENTS_DIR, &nsDirectoryService::sMovieDocumentsDirectory },
327 { NS_OSX_MUSIC_DOCUMENTS_DIR, &nsDirectoryService::sMusicDocumentsDirectory },
328 { NS_OSX_INTERNET_SITES_DIR, &nsDirectoryService::sInternetSitesDirectory },
329#elif defined (XP_UNIX)
330 { NS_UNIX_LOCAL_DIR, &nsDirectoryService::sLocalDirectory },
331 { NS_UNIX_LIB_DIR, &nsDirectoryService::sLibDirectory },
332 { NS_UNIX_HOME_DIR, &nsDirectoryService::sHomeDirectory },
333#endif
334};
335
336nsresult
337nsDirectoryService::Init()
338{
339 nsresult rv;
340
341 rv = NS_NewISupportsArray(getter_AddRefs(mProviders));
342 if (NS_FAILED(rv)) return rv;
343
344 NS_RegisterStaticAtoms(directory_atoms, NS_ARRAY_LENGTH(directory_atoms));
345
346 // Let the list hold the only reference to the provider.
347 nsAppFileLocationProvider *defaultProvider = new nsAppFileLocationProvider;
348 if (!defaultProvider)
349 return NS_ERROR_OUT_OF_MEMORY;
350 // AppendElement returns PR_TRUE for success.
351 rv = mProviders->AppendElement(defaultProvider) ? NS_OK : NS_ERROR_FAILURE;
352
353 return rv;
354}
355
356PRBool
357nsDirectoryService::ReleaseValues(nsHashKey* key, void* data, void* closure)
358{
359 nsISupports* value = (nsISupports*)data;
360 NS_IF_RELEASE(value);
361 return PR_TRUE;
362}
363
364nsDirectoryService::~nsDirectoryService()
365{
366 // clear the global
367 mService = nsnull;
368
369}
370
371NS_IMPL_THREADSAFE_ISUPPORTS4(nsDirectoryService, nsIProperties, nsIDirectoryService, nsIDirectoryServiceProvider, nsIDirectoryServiceProvider2)
372
373
374NS_IMETHODIMP
375nsDirectoryService::Undefine(const char* prop)
376{
377 nsCStringKey key(prop);
378 if (!mHashtable.Exists(&key))
379 return NS_ERROR_FAILURE;
380
381 mHashtable.Remove (&key);
382 return NS_OK;
383 }
384
385NS_IMETHODIMP
386nsDirectoryService::GetKeys(PRUint32 *count, char ***keys)
387{
388 return NS_ERROR_NOT_IMPLEMENTED;
389}
390
391struct FileData
392{
393 FileData(const char* aProperty,
394 const nsIID& aUUID) :
395 property(aProperty),
396 data(nsnull),
397 persistent(PR_TRUE),
398 uuid(aUUID) {}
399
400 const char* property;
401 nsISupports* data;
402 PRBool persistent;
403 const nsIID& uuid;
404};
405
406static PRBool FindProviderFile(nsISupports* aElement, void *aData)
407{
408 nsresult rv;
409 FileData* fileData = (FileData*)aData;
410 if (fileData->uuid.Equals(NS_GET_IID(nsISimpleEnumerator)))
411 {
412 // Not all providers implement this iface
413 nsCOMPtr<nsIDirectoryServiceProvider2> prov2 = do_QueryInterface(aElement);
414 if (prov2)
415 {
416 rv = prov2->GetFiles(fileData->property, (nsISimpleEnumerator **)&fileData->data);
417 if (NS_SUCCEEDED(rv) && fileData->data) {
418 fileData->persistent = PR_FALSE; // Enumerators can never be peristent
419 return PR_FALSE;
420 }
421 }
422 }
423 else
424 {
425 nsCOMPtr<nsIDirectoryServiceProvider> prov = do_QueryInterface(aElement);
426 if (!prov)
427 return PR_FALSE;
428 rv = prov->GetFile(fileData->property, &fileData->persistent, (nsIFile **)&fileData->data);
429 if (NS_SUCCEEDED(rv) && fileData->data)
430 return PR_FALSE;
431 }
432
433 return PR_TRUE;
434}
435
436NS_IMETHODIMP
437nsDirectoryService::Get(const char* prop, const nsIID & uuid, void* *result)
438{
439 nsCStringKey key(prop);
440
441 nsCOMPtr<nsISupports> value = dont_AddRef(mHashtable.Get(&key));
442
443 if (value)
444 {
445 nsCOMPtr<nsIFile> cloneFile;
446 nsCOMPtr<nsIFile> cachedFile = do_QueryInterface(value);
447 NS_ASSERTION(cachedFile, "nsIFile expected");
448
449 cachedFile->Clone(getter_AddRefs(cloneFile));
450 return cloneFile->QueryInterface(uuid, result);
451 }
452
453 // it is not one of our defaults, lets check any providers
454 FileData fileData(prop, uuid);
455
456 mProviders->EnumerateBackwards(FindProviderFile, &fileData);
457 if (fileData.data)
458 {
459 if (fileData.persistent)
460 {
461 Set(prop, NS_STATIC_CAST(nsIFile*, fileData.data));
462 }
463 nsresult rv = (fileData.data)->QueryInterface(uuid, result);
464 NS_RELEASE(fileData.data); // addref occurs in FindProviderFile()
465 return rv;
466 }
467
468 FindProviderFile(NS_STATIC_CAST(nsIDirectoryServiceProvider*, this), &fileData);
469 if (fileData.data)
470 {
471 if (fileData.persistent)
472 {
473 Set(prop, NS_STATIC_CAST(nsIFile*, fileData.data));
474 }
475 nsresult rv = (fileData.data)->QueryInterface(uuid, result);
476 NS_RELEASE(fileData.data); // addref occurs in FindProviderFile()
477 return rv;
478 }
479
480 return NS_ERROR_FAILURE;
481}
482
483NS_IMETHODIMP
484nsDirectoryService::Set(const char* prop, nsISupports* value)
485{
486 nsCStringKey key(prop);
487 if (mHashtable.Exists(&key) || value == nsnull)
488 return NS_ERROR_FAILURE;
489
490 nsCOMPtr<nsIFile> ourFile;
491 value->QueryInterface(NS_GET_IID(nsIFile), getter_AddRefs(ourFile));
492 if (ourFile)
493 {
494 nsCOMPtr<nsIFile> cloneFile;
495 ourFile->Clone (getter_AddRefs (cloneFile));
496 mHashtable.Put(&key, cloneFile);
497
498 return NS_OK;
499 }
500
501 return NS_ERROR_FAILURE;
502}
503
504NS_IMETHODIMP
505nsDirectoryService::Has(const char *prop, PRBool *_retval)
506{
507 *_retval = PR_FALSE;
508 nsCOMPtr<nsIFile> value;
509 nsresult rv = Get(prop, NS_GET_IID(nsIFile), getter_AddRefs(value));
510 if (NS_FAILED(rv))
511 return rv;
512
513 if (value)
514 {
515 *_retval = PR_TRUE;
516 }
517
518 return rv;
519}
520
521NS_IMETHODIMP
522nsDirectoryService::RegisterProvider(nsIDirectoryServiceProvider *prov)
523{
524 nsresult rv;
525 if (!prov)
526 return NS_ERROR_FAILURE;
527 if (!mProviders)
528 return NS_ERROR_NOT_INITIALIZED;
529
530 nsCOMPtr<nsISupports> supports = do_QueryInterface(prov, &rv);
531 if (NS_FAILED(rv)) return rv;
532
533 // AppendElement returns PR_TRUE for success.
534 return mProviders->AppendElement(supports) ? NS_OK : NS_ERROR_FAILURE;
535}
536
537NS_IMETHODIMP
538nsDirectoryService::UnregisterProvider(nsIDirectoryServiceProvider *prov)
539{
540 nsresult rv;
541 if (!prov)
542 return NS_ERROR_FAILURE;
543 if (!mProviders)
544 return NS_ERROR_NOT_INITIALIZED;
545
546 nsCOMPtr<nsISupports> supports = do_QueryInterface(prov, &rv);
547 if (NS_FAILED(rv)) return rv;
548
549 // RemoveElement returns PR_TRUE for success.
550 return mProviders->RemoveElement(supports) ? NS_OK : NS_ERROR_FAILURE;
551}
552
553// DO NOT ADD ANY LOCATIONS TO THIS FUNCTION UNTIL YOU TALK TO: dougt@netscape.com.
554// This is meant to be a place of xpcom or system specific file locations, not
555// application specific locations. If you need the later, register a callback for
556// your application.
557
558NS_IMETHODIMP
559nsDirectoryService::GetFile(const char *prop, PRBool *persistent, nsIFile **_retval)
560{
561 nsCOMPtr<nsILocalFile> localFile;
562 nsresult rv = NS_ERROR_FAILURE;
563
564 *_retval = nsnull;
565 *persistent = PR_TRUE;
566
567 nsIAtom* inAtom = NS_NewAtom(prop);
568
569 // check to see if it is one of our defaults
570
571 if (inAtom == nsDirectoryService::sCurrentProcess ||
572 inAtom == nsDirectoryService::sOS_CurrentProcessDirectory )
573 {
574 rv = GetCurrentProcessDirectory(getter_AddRefs(localFile));
575 }
576 else if (inAtom == nsDirectoryService::sComponentRegistry)
577 {
578 rv = GetCurrentProcessDirectory(getter_AddRefs(localFile));
579 if (!localFile)
580 return NS_ERROR_FAILURE;
581
582 localFile->AppendNative(COMPONENT_DIRECTORY);
583 localFile->AppendNative(COMPONENT_REGISTRY_NAME);
584 }
585 else if (inAtom == nsDirectoryService::sXPTIRegistry)
586 {
587 rv = GetCurrentProcessDirectory(getter_AddRefs(localFile));
588 if (!localFile)
589 return NS_ERROR_FAILURE;
590
591 localFile->AppendNative(COMPONENT_DIRECTORY);
592 localFile->AppendNative(XPTI_REGISTRY_NAME);
593 }
594
595 // Unless otherwise set, the core pieces of the GRE exist
596 // in the current process directory.
597 else if (inAtom == nsDirectoryService::sGRE_Directory)
598 {
599 rv = GetCurrentProcessDirectory(getter_AddRefs(localFile));
600 }
601 // the GRE components directory is relative to the GRE directory
602 // by default; applications may override this behavior in special
603 // cases
604 else if (inAtom == nsDirectoryService::sGRE_ComponentDirectory)
605 {
606 rv = Get(NS_GRE_DIR, nsILocalFile::GetIID(), getter_AddRefs(localFile));
607 if (localFile)
608 localFile->AppendNative(COMPONENT_DIRECTORY);
609 }
610 else if (inAtom == nsDirectoryService::sComponentDirectory)
611 {
612 rv = GetCurrentProcessDirectory(getter_AddRefs(localFile));
613 if (localFile)
614 localFile->AppendNative(COMPONENT_DIRECTORY);
615 }
616 else if (inAtom == nsDirectoryService::sOS_DriveDirectory)
617 {
618 rv = GetSpecialSystemDirectory(OS_DriveDirectory, getter_AddRefs(localFile));
619 }
620 else if (inAtom == nsDirectoryService::sOS_TemporaryDirectory)
621 {
622 rv = GetSpecialSystemDirectory(OS_TemporaryDirectory, getter_AddRefs(localFile));
623 }
624 else if (inAtom == nsDirectoryService::sOS_CurrentProcessDirectory)
625 {
626 rv = GetSpecialSystemDirectory(OS_CurrentProcessDirectory, getter_AddRefs(localFile));
627 }
628 else if (inAtom == nsDirectoryService::sOS_CurrentWorkingDirectory)
629 {
630 rv = GetSpecialSystemDirectory(OS_CurrentWorkingDirectory, getter_AddRefs(localFile));
631 }
632
633#if defined(XP_MACOSX)
634 else if (inAtom == nsDirectoryService::sDirectory)
635 {
636 rv = GetOSXFolderType(kClassicDomain, kSystemFolderType, getter_AddRefs(localFile));
637 }
638 else if (inAtom == nsDirectoryService::sDesktopDirectory)
639 {
640 rv = GetOSXFolderType(kClassicDomain, kDesktopFolderType, getter_AddRefs(localFile));
641 }
642 else if (inAtom == nsDirectoryService::sTrashDirectory)
643 {
644 rv = GetOSXFolderType(kClassicDomain, kTrashFolderType, getter_AddRefs(localFile));
645 }
646 else if (inAtom == nsDirectoryService::sStartupDirectory)
647 {
648 rv = GetOSXFolderType(kClassicDomain, kStartupFolderType, getter_AddRefs(localFile));
649 }
650 else if (inAtom == nsDirectoryService::sShutdownDirectory)
651 {
652 rv = GetOSXFolderType(kClassicDomain, kShutdownFolderType, getter_AddRefs(localFile));
653 }
654 else if (inAtom == nsDirectoryService::sAppleMenuDirectory)
655 {
656 rv = GetOSXFolderType(kClassicDomain, kAppleMenuFolderType, getter_AddRefs(localFile));
657 }
658 else if (inAtom == nsDirectoryService::sControlPanelDirectory)
659 {
660 rv = GetOSXFolderType(kClassicDomain, kControlPanelFolderType, getter_AddRefs(localFile));
661 }
662 else if (inAtom == nsDirectoryService::sExtensionDirectory)
663 {
664 rv = GetOSXFolderType(kClassicDomain, kExtensionFolderType, getter_AddRefs(localFile));
665 }
666 else if (inAtom == nsDirectoryService::sFontsDirectory)
667 {
668 rv = GetOSXFolderType(kClassicDomain, kFontsFolderType, getter_AddRefs(localFile));
669 }
670 else if (inAtom == nsDirectoryService::sPreferencesDirectory)
671 {
672 rv = GetOSXFolderType(kClassicDomain, kPreferencesFolderType, getter_AddRefs(localFile));
673 }
674 else if (inAtom == nsDirectoryService::sDocumentsDirectory)
675 {
676 rv = GetOSXFolderType(kClassicDomain, kDocumentsFolderType, getter_AddRefs(localFile));
677 }
678 else if (inAtom == nsDirectoryService::sInternetSearchDirectory)
679 {
680 rv = GetOSXFolderType(kClassicDomain, kInternetSearchSitesFolderType, getter_AddRefs(localFile));
681 }
682 else if (inAtom == nsDirectoryService::sUserLibDirectory)
683 {
684 rv = GetOSXFolderType(kUserDomain, kDomainLibraryFolderType, getter_AddRefs(localFile));
685 }
686 else if (inAtom == nsDirectoryService::sHomeDirectory)
687 {
688 rv = GetOSXFolderType(kUserDomain, kDomainTopLevelFolderType, getter_AddRefs(localFile));
689 }
690 else if (inAtom == nsDirectoryService::sDefaultDownloadDirectory)
691 {
692 NS_NewLocalFile(EmptyString(), PR_TRUE, getter_AddRefs(localFile));
693 nsCOMPtr<nsILocalFileMac> localMacFile(do_QueryInterface(localFile));
694
695 if (localMacFile)
696 {
697 OSErr err;
698 ICInstance icInstance;
699
700 err = ::ICStart(&icInstance, 'XPCM');
701 if (err == noErr)
702 {
703 ICAttr attrs;
704 ICFileSpec icFileSpec;
705 long size = kICFileSpecHeaderSize;
706 err = ::ICGetPref(icInstance, kICDownloadFolder, &attrs, &icFileSpec, &size);
707 if (err == noErr || (err == icTruncatedErr && size >= kICFileSpecHeaderSize))
708 {
709 rv = localMacFile->InitWithFSSpec(&icFileSpec.fss);
710 }
711 ::ICStop(icInstance);
712 }
713
714 if (NS_FAILED(rv))
715 {
716 // We got an error getting the DL folder from IC so try finding the user's Desktop folder
717 rv = GetOSXFolderType(kUserDomain, kDesktopFolderType, getter_AddRefs(localFile));
718 }
719 }
720
721 // Don't cache the DL directory as the user may change it while we're running.
722 // Negligible perf hit as this directory is only requested for downloads
723 *persistent = PR_FALSE;
724 }
725 else if (inAtom == nsDirectoryService::sUserDesktopDirectory)
726 {
727 rv = GetOSXFolderType(kUserDomain, kDesktopFolderType, getter_AddRefs(localFile));
728 }
729 else if (inAtom == nsDirectoryService::sLocalDesktopDirectory)
730 {
731 rv = GetOSXFolderType(kLocalDomain, kDesktopFolderType, getter_AddRefs(localFile));
732 }
733 else if (inAtom == nsDirectoryService::sUserApplicationsDirectory)
734 {
735 rv = GetOSXFolderType(kUserDomain, kApplicationsFolderType, getter_AddRefs(localFile));
736 }
737 else if (inAtom == nsDirectoryService::sLocalApplicationsDirectory)
738 {
739 rv = GetOSXFolderType(kLocalDomain, kApplicationsFolderType, getter_AddRefs(localFile));
740 }
741 else if (inAtom == nsDirectoryService::sUserDocumentsDirectory)
742 {
743 rv = GetOSXFolderType(kUserDomain, kDocumentsFolderType, getter_AddRefs(localFile));
744 }
745 else if (inAtom == nsDirectoryService::sLocalDocumentsDirectory)
746 {
747 rv = GetOSXFolderType(kLocalDomain, kDocumentsFolderType, getter_AddRefs(localFile));
748 }
749 else if (inAtom == nsDirectoryService::sUserInternetPlugInDirectory)
750 {
751 rv = GetOSXFolderType(kUserDomain, kInternetPlugInFolderType, getter_AddRefs(localFile));
752 }
753 else if (inAtom == nsDirectoryService::sLocalInternetPlugInDirectory)
754 {
755 rv = GetOSXFolderType(kLocalDomain, kInternetPlugInFolderType, getter_AddRefs(localFile));
756 }
757 else if (inAtom == nsDirectoryService::sUserFrameworksDirectory)
758 {
759 rv = GetOSXFolderType(kUserDomain, kFrameworksFolderType, getter_AddRefs(localFile));
760 }
761 else if (inAtom == nsDirectoryService::sLocalFrameworksDirectory)
762 {
763 rv = GetOSXFolderType(kLocalDomain, kFrameworksFolderType, getter_AddRefs(localFile));
764 }
765 else if (inAtom == nsDirectoryService::sUserPreferencesDirectory)
766 {
767 rv = GetOSXFolderType(kUserDomain, kPreferencesFolderType, getter_AddRefs(localFile));
768 }
769 else if (inAtom == nsDirectoryService::sLocalPreferencesDirectory)
770 {
771 rv = GetOSXFolderType(kLocalDomain, kPreferencesFolderType, getter_AddRefs(localFile));
772 }
773 else if (inAtom == nsDirectoryService::sPictureDocumentsDirectory)
774 {
775 rv = GetOSXFolderType(kUserDomain, kPictureDocumentsFolderType, getter_AddRefs(localFile));
776 }
777 else if (inAtom == nsDirectoryService::sMovieDocumentsDirectory)
778 {
779 rv = GetOSXFolderType(kUserDomain, kMovieDocumentsFolderType, getter_AddRefs(localFile));
780 }
781 else if (inAtom == nsDirectoryService::sMusicDocumentsDirectory)
782 {
783 rv = GetOSXFolderType(kUserDomain, kMusicDocumentsFolderType, getter_AddRefs(localFile));
784 }
785 else if (inAtom == nsDirectoryService::sInternetSitesDirectory)
786 {
787 rv = GetOSXFolderType(kUserDomain, kInternetSitesFolderType, getter_AddRefs(localFile));
788 }
789#elif defined (XP_UNIX)
790
791 else if (inAtom == nsDirectoryService::sLocalDirectory)
792 {
793 rv = GetSpecialSystemDirectory(Unix_LocalDirectory, getter_AddRefs(localFile));
794 }
795 else if (inAtom == nsDirectoryService::sLibDirectory)
796 {
797 rv = GetSpecialSystemDirectory(Unix_LibDirectory, getter_AddRefs(localFile));
798 }
799 else if (inAtom == nsDirectoryService::sHomeDirectory)
800 {
801 rv = GetSpecialSystemDirectory(Unix_HomeDirectory, getter_AddRefs(localFile));
802 }
803#endif
804
805
806 NS_RELEASE(inAtom);
807
808 if (localFile && NS_SUCCEEDED(rv))
809 return localFile->QueryInterface(NS_GET_IID(nsIFile), (void**)_retval);
810
811 return rv;
812}
813
814NS_IMETHODIMP
815nsDirectoryService::GetFiles(const char *prop, nsISimpleEnumerator **_retval)
816{
817 NS_ENSURE_ARG_POINTER(_retval);
818 *_retval = nsnull;
819
820 return NS_ERROR_FAILURE;
821}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette