VirtualBox

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

Last change on this file since 106945 was 104490, checked in by vboxsync, 7 months ago

src/libs/xpcom/io: Some smaller cleanups, fix a possible double expansion of a statement with side effects passed to a macro, bugref:3409

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