VirtualBox

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

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

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