Bug 452317 - FeedConverter.js: QueryInterface should throw NS_ERROR_NO_INTERFACE...
[wine-gecko.git] / xpcom / io / nsAppFileLocationProvider.cpp
blob20cf54716bfa7fca8597ec7a0fe82df5c82a4bba
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
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/
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.
15 * The Original Code is Mozilla Communicator client code, released
16 * March 31, 1998.
18 * The Initial Developer of the Original Code is
19 * Netscape Communications Corporation.
20 * Portions created by the Initial Developer are Copyright (C) 2000
21 * the Initial Developer. All Rights Reserved.
23 * Contributor(s):
24 * Conrad Carlen <conrad@ingress.com>
26 * Alternatively, the contents of this file may be used under the terms of
27 * either of the GNU General Public License Version 2 or later (the "GPL"),
28 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 * in which case the provisions of the GPL or the LGPL are applicable instead
30 * of those above. If you wish to allow use of your version of this file only
31 * under the terms of either the GPL or the LGPL, and not to allow others to
32 * use your version of this file under the terms of the MPL, indicate your
33 * decision by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL or the LGPL. If you do not delete
35 * the provisions above, a recipient may use your version of this file under
36 * the terms of any one of the MPL, the GPL or the LGPL.
38 * ***** END LICENSE BLOCK ***** */
40 #include "nsAppFileLocationProvider.h"
41 #include "nsAppDirectoryServiceDefs.h"
42 #include "nsDirectoryServiceDefs.h"
43 #include "nsIAtom.h"
44 #include "nsILocalFile.h"
45 #include "nsString.h"
46 #include "nsXPIDLString.h"
47 #include "nsISimpleEnumerator.h"
48 #include "prenv.h"
49 #include "nsCRT.h"
51 #if defined(XP_MACOSX)
52 #include <Folders.h>
53 #include <Script.h>
54 #include <Processes.h>
55 #include <Gestalt.h>
56 #include "nsILocalFileMac.h"
57 #elif defined(XP_OS2)
58 #define INCL_DOSPROCESS
59 #define INCL_DOSMODULEMGR
60 #include <os2.h>
61 #elif defined(XP_WIN)
62 #include <windows.h>
63 #include <shlobj.h>
64 #elif defined(XP_UNIX)
65 #include <unistd.h>
66 #include <stdlib.h>
67 #include <sys/param.h>
68 #elif defined(XP_BEOS)
69 #include <sys/param.h>
70 #include <kernel/image.h>
71 #include <storage/FindDirectory.h>
72 #endif
75 // WARNING: These hard coded names need to go away. They need to
76 // come from localizable resources
78 #if defined(XP_MACOSX)
79 #define APP_REGISTRY_NAME NS_LITERAL_CSTRING("Application Registry")
80 #define ESSENTIAL_FILES NS_LITERAL_CSTRING("Essential Files")
81 #elif defined(XP_WIN) || defined(XP_OS2)
82 #define APP_REGISTRY_NAME NS_LITERAL_CSTRING("registry.dat")
83 #else
84 #define APP_REGISTRY_NAME NS_LITERAL_CSTRING("appreg")
85 #endif
87 // define default product directory
88 #ifdef WINCE
89 #define DEFAULT_PRODUCT_DIR NS_LITERAL_CSTRING("Mozilla")
90 #else
91 #define DEFAULT_PRODUCT_DIR NS_LITERAL_CSTRING(MOZ_USER_DIR)
92 #endif
94 // Locally defined keys used by nsAppDirectoryEnumerator
95 #define NS_ENV_PLUGINS_DIR "EnvPlugins" // env var MOZ_PLUGIN_PATH
96 #define NS_USER_PLUGINS_DIR "UserPlugins"
98 #ifdef XP_MACOSX
99 #define NS_MACOSX_USER_PLUGIN_DIR "OSXUserPlugins"
100 #define NS_MACOSX_LOCAL_PLUGIN_DIR "OSXLocalPlugins"
101 #define NS_MAC_CLASSIC_PLUGIN_DIR "MacSysPlugins"
102 #endif
104 #define DEFAULTS_DIR_NAME NS_LITERAL_CSTRING("defaults")
105 #define DEFAULTS_PREF_DIR_NAME NS_LITERAL_CSTRING("pref")
106 #define DEFAULTS_PROFILE_DIR_NAME NS_LITERAL_CSTRING("profile")
107 #define RES_DIR_NAME NS_LITERAL_CSTRING("res")
108 #define CHROME_DIR_NAME NS_LITERAL_CSTRING("chrome")
109 #define PLUGINS_DIR_NAME NS_LITERAL_CSTRING("plugins")
110 #define SEARCH_DIR_NAME NS_LITERAL_CSTRING("searchplugins")
112 //*****************************************************************************
113 // nsAppFileLocationProvider::Constructor/Destructor
114 //*****************************************************************************
116 nsAppFileLocationProvider::nsAppFileLocationProvider()
120 //*****************************************************************************
121 // nsAppFileLocationProvider::nsISupports
122 //*****************************************************************************
124 NS_IMPL_THREADSAFE_ISUPPORTS2(nsAppFileLocationProvider, nsIDirectoryServiceProvider, nsIDirectoryServiceProvider2)
126 //*****************************************************************************
127 // nsAppFileLocationProvider::nsIDirectoryServiceProvider
128 //*****************************************************************************
130 NS_IMETHODIMP
131 nsAppFileLocationProvider::GetFile(const char *prop, PRBool *persistent, nsIFile **_retval)
133 nsCOMPtr<nsILocalFile> localFile;
134 nsresult rv = NS_ERROR_FAILURE;
136 NS_ENSURE_ARG(prop);
137 *_retval = nsnull;
138 *persistent = PR_TRUE;
140 #ifdef XP_MACOSX
141 short foundVRefNum;
142 long foundDirID;
143 FSSpec fileSpec;
144 nsCOMPtr<nsILocalFileMac> macFile;
145 #endif
147 if (nsCRT::strcmp(prop, NS_APP_APPLICATION_REGISTRY_DIR) == 0)
149 rv = GetProductDirectory(getter_AddRefs(localFile));
151 else if (nsCRT::strcmp(prop, NS_APP_APPLICATION_REGISTRY_FILE) == 0)
153 rv = GetProductDirectory(getter_AddRefs(localFile));
154 if (NS_SUCCEEDED(rv))
155 rv = localFile->AppendNative(APP_REGISTRY_NAME);
157 else if (nsCRT::strcmp(prop, NS_APP_DEFAULTS_50_DIR) == 0)
159 rv = CloneMozBinDirectory(getter_AddRefs(localFile));
160 if (NS_SUCCEEDED(rv))
161 rv = localFile->AppendRelativeNativePath(DEFAULTS_DIR_NAME);
163 else if (nsCRT::strcmp(prop, NS_APP_PREF_DEFAULTS_50_DIR) == 0)
165 rv = CloneMozBinDirectory(getter_AddRefs(localFile));
166 if (NS_SUCCEEDED(rv)) {
167 rv = localFile->AppendRelativeNativePath(DEFAULTS_DIR_NAME);
168 if (NS_SUCCEEDED(rv))
169 rv = localFile->AppendRelativeNativePath(DEFAULTS_PREF_DIR_NAME);
172 else if (nsCRT::strcmp(prop, NS_APP_PROFILE_DEFAULTS_50_DIR) == 0 ||
173 nsCRT::strcmp(prop, NS_APP_PROFILE_DEFAULTS_NLOC_50_DIR) == 0)
175 rv = CloneMozBinDirectory(getter_AddRefs(localFile));
176 if (NS_SUCCEEDED(rv)) {
177 rv = localFile->AppendRelativeNativePath(DEFAULTS_DIR_NAME);
178 if (NS_SUCCEEDED(rv))
179 rv = localFile->AppendRelativeNativePath(DEFAULTS_PROFILE_DIR_NAME);
182 else if (nsCRT::strcmp(prop, NS_APP_USER_PROFILES_ROOT_DIR) == 0)
184 rv = GetDefaultUserProfileRoot(getter_AddRefs(localFile));
186 else if (nsCRT::strcmp(prop, NS_APP_USER_PROFILES_LOCAL_ROOT_DIR) == 0)
188 rv = GetDefaultUserProfileRoot(getter_AddRefs(localFile), PR_TRUE);
190 else if (nsCRT::strcmp(prop, NS_APP_RES_DIR) == 0)
192 rv = CloneMozBinDirectory(getter_AddRefs(localFile));
193 if (NS_SUCCEEDED(rv))
194 rv = localFile->AppendRelativeNativePath(RES_DIR_NAME);
196 else if (nsCRT::strcmp(prop, NS_APP_CHROME_DIR) == 0)
198 rv = CloneMozBinDirectory(getter_AddRefs(localFile));
199 if (NS_SUCCEEDED(rv))
200 rv = localFile->AppendRelativeNativePath(CHROME_DIR_NAME);
202 else if (nsCRT::strcmp(prop, NS_APP_PLUGINS_DIR) == 0)
204 rv = CloneMozBinDirectory(getter_AddRefs(localFile));
205 if (NS_SUCCEEDED(rv))
206 rv = localFile->AppendRelativeNativePath(PLUGINS_DIR_NAME);
208 #ifdef XP_MACOSX
209 else if (nsCRT::strcmp(prop, NS_MACOSX_USER_PLUGIN_DIR) == 0)
211 if (!(::FindFolder(kUserDomain,
212 kInternetPlugInFolderType,
213 kDontCreateFolder, &foundVRefNum, &foundDirID)) &&
214 !(::FSMakeFSSpec(foundVRefNum, foundDirID, "\p", &fileSpec))) {
215 rv = NS_NewLocalFileWithFSSpec(&fileSpec, PR_TRUE, getter_AddRefs(macFile));
216 if (NS_SUCCEEDED(rv))
217 localFile = macFile;
220 else if (nsCRT::strcmp(prop, NS_MACOSX_LOCAL_PLUGIN_DIR) == 0)
222 if (!(::FindFolder(kLocalDomain,
223 kInternetPlugInFolderType,
224 kDontCreateFolder, &foundVRefNum, &foundDirID)) &&
225 !(::FSMakeFSSpec(foundVRefNum, foundDirID, "\p", &fileSpec))) {
226 rv = NS_NewLocalFileWithFSSpec(&fileSpec, PR_TRUE, getter_AddRefs(macFile));
227 if (NS_SUCCEEDED(rv))
228 localFile = macFile;
231 else if (nsCRT::strcmp(prop, NS_MAC_CLASSIC_PLUGIN_DIR) == 0)
233 if (!(::FindFolder(kOnAppropriateDisk,
234 kInternetPlugInFolderType,
235 kDontCreateFolder, &foundVRefNum, &foundDirID)) &&
236 !(::FSMakeFSSpec(foundVRefNum, foundDirID, "\p", &fileSpec))) {
237 rv = NS_NewLocalFileWithFSSpec(&fileSpec, PR_TRUE, getter_AddRefs(macFile));
238 if (NS_SUCCEEDED(rv))
239 localFile = macFile;
242 #else
243 else if (nsCRT::strcmp(prop, NS_ENV_PLUGINS_DIR) == 0)
245 NS_ERROR("Don't use nsAppFileLocationProvider::GetFile(NS_ENV_PLUGINS_DIR, ...). "
246 "Use nsAppFileLocationProvider::GetFiles(...).");
247 const char *pathVar = PR_GetEnv("MOZ_PLUGIN_PATH");
248 if (pathVar && *pathVar)
249 rv = NS_NewNativeLocalFile(nsDependentCString(pathVar), PR_TRUE, getter_AddRefs(localFile));
251 else if (nsCRT::strcmp(prop, NS_USER_PLUGINS_DIR) == 0)
253 rv = GetProductDirectory(getter_AddRefs(localFile));
254 if (NS_SUCCEEDED(rv))
255 rv = localFile->AppendRelativeNativePath(PLUGINS_DIR_NAME);
257 #endif
258 else if (nsCRT::strcmp(prop, NS_APP_SEARCH_DIR) == 0)
260 rv = CloneMozBinDirectory(getter_AddRefs(localFile));
261 if (NS_SUCCEEDED(rv))
262 rv = localFile->AppendRelativeNativePath(SEARCH_DIR_NAME);
264 else if (nsCRT::strcmp(prop, NS_APP_USER_SEARCH_DIR) == 0)
266 rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, _retval);
267 if (NS_SUCCEEDED(rv))
268 rv = (*_retval)->AppendNative(SEARCH_DIR_NAME);
270 else if (nsCRT::strcmp(prop, NS_APP_INSTALL_CLEANUP_DIR) == 0)
272 // This is cloned so that embeddors will have a hook to override
273 // with their own cleanup dir. See bugzilla bug #105087
274 rv = CloneMozBinDirectory(getter_AddRefs(localFile));
277 if (localFile && NS_SUCCEEDED(rv))
278 return localFile->QueryInterface(NS_GET_IID(nsIFile), (void**)_retval);
280 return rv;
284 NS_METHOD nsAppFileLocationProvider::CloneMozBinDirectory(nsILocalFile **aLocalFile)
286 NS_ENSURE_ARG_POINTER(aLocalFile);
287 nsresult rv;
289 if (!mMozBinDirectory)
291 // Get the mozilla bin directory
292 // 1. Check the directory service first for NS_XPCOM_CURRENT_PROCESS_DIR
293 // This will be set if a directory was passed to NS_InitXPCOM
294 // 2. If that doesn't work, set it to be the current process directory
295 nsCOMPtr<nsIProperties>
296 directoryService(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv));
297 if (NS_FAILED(rv))
298 return rv;
300 rv = directoryService->Get(NS_XPCOM_CURRENT_PROCESS_DIR, NS_GET_IID(nsIFile), getter_AddRefs(mMozBinDirectory));
301 if (NS_FAILED(rv)) {
302 rv = directoryService->Get(NS_OS_CURRENT_PROCESS_DIR, NS_GET_IID(nsIFile), getter_AddRefs(mMozBinDirectory));
303 if (NS_FAILED(rv))
304 return rv;
308 nsCOMPtr<nsIFile> aFile;
309 rv = mMozBinDirectory->Clone(getter_AddRefs(aFile));
310 if (NS_FAILED(rv))
311 return rv;
313 nsCOMPtr<nsILocalFile> lfile = do_QueryInterface (aFile);
314 if (!lfile)
315 return NS_ERROR_FAILURE;
317 NS_IF_ADDREF(*aLocalFile = lfile);
318 return NS_OK;
322 //----------------------------------------------------------------------------------------
323 // GetProductDirectory - Gets the directory which contains the application data folder
325 // UNIX : ~/.mozilla/
326 // WIN : <Application Data folder on user's machine>\Mozilla
327 // Mac : :Documents:Mozilla:
328 //----------------------------------------------------------------------------------------
329 NS_METHOD nsAppFileLocationProvider::GetProductDirectory(nsILocalFile **aLocalFile, PRBool aLocal)
331 NS_ENSURE_ARG_POINTER(aLocalFile);
333 nsresult rv;
334 PRBool exists;
335 nsCOMPtr<nsILocalFile> localDir;
337 #if defined(XP_MACOSX)
338 FSRef fsRef;
339 OSType folderType = aLocal ? kCachedDataFolderType : kDomainLibraryFolderType;
340 OSErr err = ::FSFindFolder(kUserDomain, folderType, kCreateFolder, &fsRef);
341 if (err) return NS_ERROR_FAILURE;
342 NS_NewLocalFile(EmptyString(), PR_TRUE, getter_AddRefs(localDir));
343 if (!localDir) return NS_ERROR_FAILURE;
344 nsCOMPtr<nsILocalFileMac> localDirMac(do_QueryInterface(localDir));
345 rv = localDirMac->InitWithFSRef(&fsRef);
346 if (NS_FAILED(rv)) return rv;
347 #elif defined(XP_OS2)
348 nsCOMPtr<nsIProperties> directoryService =
349 do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv);
350 if (NS_FAILED(rv)) return rv;
351 rv = directoryService->Get(NS_OS2_HOME_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(localDir));
352 if (NS_FAILED(rv)) return rv;
353 #elif defined(WINCE)
354 nsCOMPtr<nsIProperties> directoryService =
355 do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv);
356 if (NS_FAILED(rv)) return rv;
358 directoryService->Get(NS_XPCOM_CURRENT_PROCESS_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(localDir));
359 if (localDir)
360 rv = localDir->AppendNative(NS_LITERAL_CSTRING("profile"));
361 if (NS_FAILED(rv)) return rv;
362 #elif defined(XP_WIN)
363 nsCOMPtr<nsIProperties> directoryService =
364 do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv);
365 if (NS_FAILED(rv)) return rv;
366 const char* prop = aLocal ? NS_WIN_LOCAL_APPDATA_DIR : NS_WIN_APPDATA_DIR;
367 rv = directoryService->Get(prop, NS_GET_IID(nsILocalFile), getter_AddRefs(localDir));
368 if (NS_SUCCEEDED(rv))
369 rv = localDir->Exists(&exists);
370 if (NS_FAILED(rv) || !exists)
372 // On some Win95 machines, NS_WIN_APPDATA_DIR does not exist - revert to NS_WIN_WINDOWS_DIR
373 localDir = nsnull;
374 rv = directoryService->Get(NS_WIN_WINDOWS_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(localDir));
376 if (NS_FAILED(rv)) return rv;
377 #elif defined(XP_UNIX)
378 rv = NS_NewNativeLocalFile(nsDependentCString(PR_GetEnv("HOME")), PR_TRUE, getter_AddRefs(localDir));
379 if (NS_FAILED(rv)) return rv;
380 #elif defined(XP_BEOS)
381 char path[MAXPATHLEN];
382 find_directory(B_USER_SETTINGS_DIRECTORY, 0, 0, path, MAXPATHLEN);
383 // Need enough space to add the trailing backslash
384 int len = strlen(path);
385 if (len > MAXPATHLEN-2)
386 return NS_ERROR_FAILURE;
387 path[len] = '/';
388 path[len+1] = '\0';
389 rv = NS_NewNativeLocalFile(nsDependentCString(path), PR_TRUE, getter_AddRefs(localDir));
390 if (NS_FAILED(rv)) return rv;
391 #else
392 #error dont_know_how_to_get_product_dir_on_your_platform
393 #endif
395 rv = localDir->AppendRelativeNativePath(DEFAULT_PRODUCT_DIR);
396 if (NS_FAILED(rv)) return rv;
397 rv = localDir->Exists(&exists);
399 if (NS_SUCCEEDED(rv) && !exists)
400 rv = localDir->Create(nsIFile::DIRECTORY_TYPE, 0700);
402 if (NS_FAILED(rv)) return rv;
404 *aLocalFile = localDir;
405 NS_ADDREF(*aLocalFile);
407 return rv;
411 //----------------------------------------------------------------------------------------
412 // GetDefaultUserProfileRoot - Gets the directory which contains each user profile dir
414 // UNIX : ~/.mozilla/
415 // WIN : <Application Data folder on user's machine>\Mozilla\Profiles
416 // Mac : :Documents:Mozilla:Profiles:
417 //----------------------------------------------------------------------------------------
418 NS_METHOD nsAppFileLocationProvider::GetDefaultUserProfileRoot(nsILocalFile **aLocalFile, PRBool aLocal)
420 NS_ENSURE_ARG_POINTER(aLocalFile);
422 nsresult rv;
423 nsCOMPtr<nsILocalFile> localDir;
425 rv = GetProductDirectory(getter_AddRefs(localDir), aLocal);
426 if (NS_FAILED(rv)) return rv;
428 #if defined(XP_MACOSX) || defined(XP_OS2) || defined(XP_WIN)
429 // These 3 platforms share this part of the path - do them as one
430 rv = localDir->AppendRelativeNativePath(NS_LITERAL_CSTRING("Profiles"));
431 if (NS_FAILED(rv)) return rv;
433 PRBool exists;
434 rv = localDir->Exists(&exists);
435 if (NS_SUCCEEDED(rv) && !exists)
436 rv = localDir->Create(nsIFile::DIRECTORY_TYPE, 0775);
437 if (NS_FAILED(rv)) return rv;
438 #endif
440 *aLocalFile = localDir;
441 NS_ADDREF(*aLocalFile);
443 return rv;
446 //*****************************************************************************
447 // nsAppFileLocationProvider::nsIDirectoryServiceProvider2
448 //*****************************************************************************
450 class nsAppDirectoryEnumerator : public nsISimpleEnumerator
452 public:
453 NS_DECL_ISUPPORTS
456 * aKeyList is a null-terminated list of properties which are provided by aProvider
457 * They do not need to be publicly defined keys.
459 nsAppDirectoryEnumerator(nsIDirectoryServiceProvider *aProvider,
460 const char* aKeyList[]) :
461 mProvider(aProvider),
462 mCurrentKey(aKeyList)
466 NS_IMETHOD HasMoreElements(PRBool *result)
468 while (!mNext && *mCurrentKey)
470 PRBool dontCare;
471 nsCOMPtr<nsIFile> testFile;
472 (void)mProvider->GetFile(*mCurrentKey++, &dontCare, getter_AddRefs(testFile));
473 // Don't return a file which does not exist.
474 PRBool exists;
475 if (testFile && NS_SUCCEEDED(testFile->Exists(&exists)) && exists)
476 mNext = testFile;
478 *result = mNext != nsnull;
479 return NS_OK;
482 NS_IMETHOD GetNext(nsISupports **result)
484 NS_ENSURE_ARG_POINTER(result);
485 *result = nsnull;
487 PRBool hasMore;
488 HasMoreElements(&hasMore);
489 if (!hasMore)
490 return NS_ERROR_FAILURE;
492 *result = mNext;
493 NS_IF_ADDREF(*result);
494 mNext = nsnull;
496 return *result ? NS_OK : NS_ERROR_FAILURE;
499 // Virtual destructor since subclass nsPathsDirectoryEnumerator
500 // does not re-implement Release()
502 virtual ~nsAppDirectoryEnumerator()
506 protected:
507 nsIDirectoryServiceProvider *mProvider;
508 const char** mCurrentKey;
509 nsCOMPtr<nsIFile> mNext;
512 NS_IMPL_ISUPPORTS1(nsAppDirectoryEnumerator, nsISimpleEnumerator)
514 /* nsPathsDirectoryEnumerator and PATH_SEPARATOR
515 * are not used on MacOS/X. */
517 #if defined(XP_WIN) || defined(XP_OS2)/* Win32, Win16, and OS/2 */
518 #define PATH_SEPARATOR ';'
519 #else /*if defined(XP_UNIX) || defined(XP_BEOS)*/
520 #define PATH_SEPARATOR ':'
521 #endif
523 class nsPathsDirectoryEnumerator : public nsAppDirectoryEnumerator
525 public:
527 * aKeyList is a null-terminated list.
528 * The first element is a path list.
529 * The remainder are properties provided by aProvider.
530 * They do not need to be publicly defined keys.
532 nsPathsDirectoryEnumerator(nsIDirectoryServiceProvider *aProvider,
533 const char* aKeyList[]) :
534 nsAppDirectoryEnumerator(aProvider, aKeyList+1),
535 mEndPath(aKeyList[0])
539 NS_IMETHOD HasMoreElements(PRBool *result)
541 if (mEndPath)
542 while (!mNext && *mEndPath)
544 const char *pathVar = mEndPath;
546 // skip PATH_SEPARATORs at the begining of the mEndPath
547 while (*pathVar == PATH_SEPARATOR) pathVar++;
549 do { ++mEndPath; } while (*mEndPath && *mEndPath != PATH_SEPARATOR);
551 nsCOMPtr<nsILocalFile> localFile;
552 NS_NewNativeLocalFile(Substring(pathVar, mEndPath),
553 PR_TRUE,
554 getter_AddRefs(localFile));
555 if (*mEndPath == PATH_SEPARATOR)
556 ++mEndPath;
557 // Don't return a "file" (directory) which does not exist.
558 PRBool exists;
559 if (localFile &&
560 NS_SUCCEEDED(localFile->Exists(&exists)) &&
561 exists)
562 mNext = localFile;
564 if (mNext)
565 *result = PR_TRUE;
566 else
567 nsAppDirectoryEnumerator::HasMoreElements(result);
569 return NS_OK;
572 protected:
573 const char *mEndPath;
576 NS_IMETHODIMP
577 nsAppFileLocationProvider::GetFiles(const char *prop, nsISimpleEnumerator **_retval)
579 NS_ENSURE_ARG_POINTER(_retval);
580 *_retval = nsnull;
581 nsresult rv = NS_ERROR_FAILURE;
583 if (!nsCRT::strcmp(prop, NS_APP_PLUGINS_DIR_LIST))
585 #ifdef XP_MACOSX
586 static const char* osXKeys[] = { NS_APP_PLUGINS_DIR, NS_MACOSX_USER_PLUGIN_DIR, NS_MACOSX_LOCAL_PLUGIN_DIR, nsnull };
587 static const char* os9Keys[] = { NS_APP_PLUGINS_DIR, NS_MAC_CLASSIC_PLUGIN_DIR, nsnull };
588 static const char** keys;
590 if (!keys) {
591 OSErr err;
592 long response;
593 err = ::Gestalt(gestaltSystemVersion, &response);
594 keys = (!err && response >= 0x00001000) ? osXKeys : os9Keys;
597 *_retval = new nsAppDirectoryEnumerator(this, keys);
598 #else
599 static const char* keys[] = { nsnull, NS_USER_PLUGINS_DIR, NS_APP_PLUGINS_DIR, nsnull };
600 if (!keys[0] && !(keys[0] = PR_GetEnv("MOZ_PLUGIN_PATH"))) {
601 static const char nullstr = 0;
602 keys[0] = &nullstr;
604 *_retval = new nsPathsDirectoryEnumerator(this, keys);
605 #endif
606 NS_IF_ADDREF(*_retval);
607 rv = *_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
609 if (!nsCRT::strcmp(prop, NS_APP_SEARCH_DIR_LIST))
611 static const char* keys[] = { nsnull, NS_APP_SEARCH_DIR, NS_APP_USER_SEARCH_DIR, nsnull };
612 if (!keys[0] && !(keys[0] = PR_GetEnv("MOZ_SEARCH_ENGINE_PATH"))) {
613 static const char nullstr = 0;
614 keys[0] = &nullstr;
616 *_retval = new nsPathsDirectoryEnumerator(this, keys);
617 NS_IF_ADDREF(*_retval);
618 rv = *_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
620 return rv;