VirtualBox

source: vbox/trunk/src/libs/xpcom18a4/xpcom/io/nsAppFileLocationProvider.cpp@ 16402

最後變更 在這個檔案從16402是 16402,由 vboxsync 提交於 16 年 前

XPCOM-darwin/amd64: Replaced ugly expression with VBOX_MACOSX_FOLLOWS_UNIX_IO.

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 22.0 KB
 
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 Communicator client code, released
16 * March 31, 1998.
17 *
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.
22 *
23 * Contributor(s):
24 * Conrad Carlen <[email protected]>
25 *
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.
37 *
38 * ***** END LICENSE BLOCK ***** */
39
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"
50
51#if (defined(XP_MAC) || defined(XP_MACOSX)) && !defined(VBOX_MACOSX_FOLLOWS_UNIX_IO)
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
73
74
75// WARNING: These hard coded names need to go away. They need to
76// come from localizable resources
77
78#if defined(XP_MAC) || 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
86
87// define default product directory
88#ifdef XP_MAC
89#define DEFAULT_PRODUCT_DIR NS_LITERAL_CSTRING("Mozilla")
90#else
91#define DEFAULT_PRODUCT_DIR NS_LITERAL_CSTRING(MOZ_USER_DIR)
92#endif
93
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"
97
98#if defined(XP_MAC) || defined(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
103
104#if defined(XP_MAC)
105#define DEFAULTS_DIR_NAME NS_LITERAL_CSTRING("Defaults")
106#define DEFAULTS_PREF_DIR_NAME NS_LITERAL_CSTRING("Pref")
107#define DEFAULTS_PROFILE_DIR_NAME NS_LITERAL_CSTRING("Profile")
108#define RES_DIR_NAME NS_LITERAL_CSTRING("Res")
109#define CHROME_DIR_NAME NS_LITERAL_CSTRING("Chrome")
110#define PLUGINS_DIR_NAME NS_LITERAL_CSTRING("Plug-ins")
111#define SEARCH_DIR_NAME NS_LITERAL_CSTRING("Search Plugins")
112#else
113#define DEFAULTS_DIR_NAME NS_LITERAL_CSTRING("defaults")
114#define DEFAULTS_PREF_DIR_NAME NS_LITERAL_CSTRING("pref")
115#define DEFAULTS_PROFILE_DIR_NAME NS_LITERAL_CSTRING("profile")
116#define RES_DIR_NAME NS_LITERAL_CSTRING("res")
117#define CHROME_DIR_NAME NS_LITERAL_CSTRING("chrome")
118#define PLUGINS_DIR_NAME NS_LITERAL_CSTRING("plugins")
119#define SEARCH_DIR_NAME NS_LITERAL_CSTRING("searchplugins")
120#endif
121
122//*****************************************************************************
123// nsAppFileLocationProvider::Constructor/Destructor
124//*****************************************************************************
125
126nsAppFileLocationProvider::nsAppFileLocationProvider()
127{
128}
129
130//*****************************************************************************
131// nsAppFileLocationProvider::nsISupports
132//*****************************************************************************
133
134NS_IMPL_THREADSAFE_ISUPPORTS2(nsAppFileLocationProvider, nsIDirectoryServiceProvider, nsIDirectoryServiceProvider2)
135
136//*****************************************************************************
137// nsAppFileLocationProvider::nsIDirectoryServiceProvider
138//*****************************************************************************
139
140NS_IMETHODIMP
141nsAppFileLocationProvider::GetFile(const char *prop, PRBool *persistant, nsIFile **_retval)
142{
143 nsCOMPtr<nsILocalFile> localFile;
144 nsresult rv = NS_ERROR_FAILURE;
145
146 NS_ENSURE_ARG(prop);
147 *_retval = nsnull;
148 *persistant = PR_TRUE;
149
150#if (defined (XP_MAC) || defined(XP_MACOSX)) && !defined(VBOX_MACOSX_FOLLOWS_UNIX_IO)
151 short foundVRefNum;
152 long foundDirID;
153 FSSpec fileSpec;
154 nsCOMPtr<nsILocalFileMac> macFile;
155#endif
156
157 if (nsCRT::strcmp(prop, NS_APP_APPLICATION_REGISTRY_DIR) == 0)
158 {
159 rv = GetProductDirectory(getter_AddRefs(localFile));
160 }
161 else if (nsCRT::strcmp(prop, NS_APP_APPLICATION_REGISTRY_FILE) == 0)
162 {
163 rv = GetProductDirectory(getter_AddRefs(localFile));
164 if (NS_SUCCEEDED(rv))
165 rv = localFile->AppendNative(APP_REGISTRY_NAME);
166 }
167 else if (nsCRT::strcmp(prop, NS_APP_DEFAULTS_50_DIR) == 0)
168 {
169 rv = CloneMozBinDirectory(getter_AddRefs(localFile));
170 if (NS_SUCCEEDED(rv))
171 rv = localFile->AppendRelativeNativePath(DEFAULTS_DIR_NAME);
172 }
173 else if (nsCRT::strcmp(prop, NS_APP_PREF_DEFAULTS_50_DIR) == 0)
174 {
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_PREF_DIR_NAME);
180 }
181 }
182 else if (nsCRT::strcmp(prop, NS_APP_PROFILE_DEFAULTS_50_DIR) == 0 ||
183 nsCRT::strcmp(prop, NS_APP_PROFILE_DEFAULTS_NLOC_50_DIR) == 0)
184 {
185 rv = CloneMozBinDirectory(getter_AddRefs(localFile));
186 if (NS_SUCCEEDED(rv)) {
187 rv = localFile->AppendRelativeNativePath(DEFAULTS_DIR_NAME);
188 if (NS_SUCCEEDED(rv))
189 rv = localFile->AppendRelativeNativePath(DEFAULTS_PROFILE_DIR_NAME);
190 }
191 }
192 else if (nsCRT::strcmp(prop, NS_APP_USER_PROFILES_ROOT_DIR) == 0)
193 {
194 rv = GetDefaultUserProfileRoot(getter_AddRefs(localFile));
195 }
196 else if (nsCRT::strcmp(prop, NS_APP_RES_DIR) == 0)
197 {
198 rv = CloneMozBinDirectory(getter_AddRefs(localFile));
199 if (NS_SUCCEEDED(rv))
200 rv = localFile->AppendRelativeNativePath(RES_DIR_NAME);
201 }
202 else if (nsCRT::strcmp(prop, NS_APP_CHROME_DIR) == 0)
203 {
204 rv = CloneMozBinDirectory(getter_AddRefs(localFile));
205 if (NS_SUCCEEDED(rv))
206 rv = localFile->AppendRelativeNativePath(CHROME_DIR_NAME);
207 }
208 else if (nsCRT::strcmp(prop, NS_APP_PLUGINS_DIR) == 0)
209 {
210 rv = CloneMozBinDirectory(getter_AddRefs(localFile));
211 if (NS_SUCCEEDED(rv))
212 rv = localFile->AppendRelativeNativePath(PLUGINS_DIR_NAME);
213 }
214#if (defined(XP_MAC) || defined(XP_MACOSX)) && !defined(VBOX_MACOSX_FOLLOWS_UNIX_IO)
215 else if (nsCRT::strcmp(prop, NS_MACOSX_USER_PLUGIN_DIR) == 0)
216 {
217 if (!(::FindFolder(kUserDomain,
218 kInternetPlugInFolderType,
219 kDontCreateFolder, &foundVRefNum, &foundDirID)) &&
220 !(::FSMakeFSSpec(foundVRefNum, foundDirID, "\p", &fileSpec))) {
221 rv = NS_NewLocalFileWithFSSpec(&fileSpec, PR_TRUE, getter_AddRefs(macFile));
222 if (NS_SUCCEEDED(rv))
223 localFile = macFile;
224 }
225 }
226 else if (nsCRT::strcmp(prop, NS_MACOSX_LOCAL_PLUGIN_DIR) == 0)
227 {
228 if (!(::FindFolder(kLocalDomain,
229 kInternetPlugInFolderType,
230 kDontCreateFolder, &foundVRefNum, &foundDirID)) &&
231 !(::FSMakeFSSpec(foundVRefNum, foundDirID, "\p", &fileSpec))) {
232 rv = NS_NewLocalFileWithFSSpec(&fileSpec, PR_TRUE, getter_AddRefs(macFile));
233 if (NS_SUCCEEDED(rv))
234 localFile = macFile;
235 }
236 }
237 else if (nsCRT::strcmp(prop, NS_MAC_CLASSIC_PLUGIN_DIR) == 0)
238 {
239 if (!(::FindFolder(kOnAppropriateDisk,
240 kInternetPlugInFolderType,
241 kDontCreateFolder, &foundVRefNum, &foundDirID)) &&
242 !(::FSMakeFSSpec(foundVRefNum, foundDirID, "\p", &fileSpec))) {
243 rv = NS_NewLocalFileWithFSSpec(&fileSpec, PR_TRUE, getter_AddRefs(macFile));
244 if (NS_SUCCEEDED(rv))
245 localFile = macFile;
246 }
247 }
248#else
249 else if (nsCRT::strcmp(prop, NS_ENV_PLUGINS_DIR) == 0)
250 {
251 NS_ERROR("Don't use nsAppFileLocationProvider::GetFile(NS_ENV_PLUGINS_DIR, ...). "
252 "Use nsAppFileLocationProvider::GetFiles(...).");
253 const char *pathVar = PR_GetEnv("VBOX_XPCOM_PLUGIN_PATH");
254 if (pathVar)
255 rv = NS_NewNativeLocalFile(nsDependentCString(pathVar), PR_TRUE, getter_AddRefs(localFile));
256 }
257 else if (nsCRT::strcmp(prop, NS_USER_PLUGINS_DIR) == 0)
258 {
259 rv = GetProductDirectory(getter_AddRefs(localFile));
260 if (NS_SUCCEEDED(rv))
261 rv = localFile->AppendRelativeNativePath(PLUGINS_DIR_NAME);
262 }
263#endif
264 else if (nsCRT::strcmp(prop, NS_APP_SEARCH_DIR) == 0)
265 {
266 rv = CloneMozBinDirectory(getter_AddRefs(localFile));
267 if (NS_SUCCEEDED(rv))
268 rv = localFile->AppendRelativeNativePath(SEARCH_DIR_NAME);
269 }
270 else if (nsCRT::strcmp(prop, NS_APP_INSTALL_CLEANUP_DIR) == 0)
271 {
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));
275#ifdef XP_MAC
276 if (NS_SUCCEEDED(rv))
277 rv = localFile->AppendNative(ESSENTIAL_FILES);
278#endif
279
280 }
281
282 if (localFile && NS_SUCCEEDED(rv))
283 return localFile->QueryInterface(NS_GET_IID(nsIFile), (void**)_retval);
284
285 return rv;
286}
287
288
289NS_METHOD nsAppFileLocationProvider::CloneMozBinDirectory(nsILocalFile **aLocalFile)
290{
291 NS_ENSURE_ARG_POINTER(aLocalFile);
292 nsresult rv;
293
294 if (!mMozBinDirectory)
295 {
296 // Get the mozilla bin directory
297 // 1. Check the directory service first for NS_XPCOM_CURRENT_PROCESS_DIR
298 // This will be set if a directory was passed to NS_InitXPCOM
299 // 2. If that doesn't work, set it to be the current process directory
300 nsCOMPtr<nsIProperties>
301 directoryService(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv));
302 if (NS_FAILED(rv))
303 return rv;
304
305 rv = directoryService->Get(NS_XPCOM_CURRENT_PROCESS_DIR, NS_GET_IID(nsIFile), getter_AddRefs(mMozBinDirectory));
306 if (NS_FAILED(rv)) {
307 rv = directoryService->Get(NS_OS_CURRENT_PROCESS_DIR, NS_GET_IID(nsIFile), getter_AddRefs(mMozBinDirectory));
308 if (NS_FAILED(rv))
309 return rv;
310 }
311 }
312
313 nsCOMPtr<nsIFile> aFile;
314 rv = mMozBinDirectory->Clone(getter_AddRefs(aFile));
315 if (NS_FAILED(rv))
316 return rv;
317
318 nsCOMPtr<nsILocalFile> lfile = do_QueryInterface (aFile);
319 if (!lfile)
320 return NS_ERROR_FAILURE;
321
322 NS_IF_ADDREF(*aLocalFile = lfile);
323 return NS_OK;
324}
325
326
327//----------------------------------------------------------------------------------------
328// GetProductDirectory - Gets the directory which contains the application data folder
329//
330// UNIX : ~/.mozilla/
331// WIN : <Application Data folder on user's machine>\Mozilla
332// Mac : :Documents:Mozilla:
333//----------------------------------------------------------------------------------------
334NS_METHOD nsAppFileLocationProvider::GetProductDirectory(nsILocalFile **aLocalFile)
335{
336 NS_ENSURE_ARG_POINTER(aLocalFile);
337
338 nsresult rv;
339 PRBool exists;
340 nsCOMPtr<nsILocalFile> localDir;
341
342#if defined(XP_MAC)
343 nsCOMPtr<nsIProperties> directoryService =
344 do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv);
345 if (NS_FAILED(rv)) return rv;
346 OSErr err;
347 long response;
348 err = ::Gestalt(gestaltSystemVersion, &response);
349 const char *prop = (!err && response >= 0x00001000) ? NS_MAC_USER_LIB_DIR : NS_MAC_DOCUMENTS_DIR;
350 rv = directoryService->Get(prop, NS_GET_IID(nsILocalFile), getter_AddRefs(localDir));
351 if (NS_FAILED(rv)) return rv;
352#elif defined(XP_MACOSX) && !defined(VBOX_MACOSX_FOLLOWS_UNIX_IO)
353 FSRef fsRef;
354 OSErr err = ::FSFindFolder(kUserDomain, kDomainLibraryFolderType, kCreateFolder, &fsRef);
355 if (err) return NS_ERROR_FAILURE;
356 NS_NewLocalFile(EmptyString(), PR_TRUE, getter_AddRefs(localDir));
357 if (!localDir) return NS_ERROR_FAILURE;
358 nsCOMPtr<nsILocalFileMac> localDirMac(do_QueryInterface(localDir));
359 rv = localDirMac->InitWithFSRef(&fsRef);
360 if (NS_FAILED(rv)) return rv;
361#elif defined(XP_OS2)
362 nsCOMPtr<nsIProperties> directoryService =
363 do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv);
364 if (NS_FAILED(rv)) return rv;
365 rv = directoryService->Get(NS_OS2_HOME_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(localDir));
366 if (NS_FAILED(rv)) return rv;
367#elif defined(XP_WIN)
368 nsCOMPtr<nsIProperties> directoryService =
369 do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv);
370 if (NS_FAILED(rv)) return rv;
371 rv = directoryService->Get(NS_WIN_APPDATA_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(localDir));
372 if (NS_SUCCEEDED(rv))
373 rv = localDir->Exists(&exists);
374 if (NS_FAILED(rv) || !exists)
375 {
376 // On some Win95 machines, NS_WIN_APPDATA_DIR does not exist - revert to NS_WIN_WINDOWS_DIR
377 localDir = nsnull;
378 rv = directoryService->Get(NS_WIN_WINDOWS_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(localDir));
379 }
380 if (NS_FAILED(rv)) return rv;
381#elif defined(L4ENV)
382 /* Major hack attack, should sort out the environment stuff!!! */
383 rv = NS_NewNativeLocalFile(nsDependentCString("."), PR_TRUE, getter_AddRefs(localDir));
384 if (NS_FAILED(rv)) return rv;
385#elif defined(XP_UNIX)
386 rv = NS_NewNativeLocalFile(nsDependentCString(PR_GetEnv("HOME")), PR_TRUE, getter_AddRefs(localDir));
387 if (NS_FAILED(rv)) return rv;
388#elif defined(XP_BEOS)
389 char path[MAXPATHLEN];
390 find_directory(B_USER_SETTINGS_DIRECTORY, 0, 0, path, MAXPATHLEN);
391 // Need enough space to add the trailing backslash
392 int len = strlen(path);
393 if (len > MAXPATHLEN-2)
394 return NS_ERROR_FAILURE;
395 path[len] = '/';
396 path[len+1] = '\0';
397 rv = NS_NewNativeLocalFile(nsDependentCString(path), PR_TRUE, getter_AddRefs(localDir));
398 if (NS_FAILED(rv)) return rv;
399#else
400#error dont_know_how_to_get_product_dir_on_your_platform
401#endif
402
403 rv = localDir->AppendRelativeNativePath(DEFAULT_PRODUCT_DIR);
404 if (NS_FAILED(rv)) return rv;
405 rv = localDir->Exists(&exists);
406 if (NS_SUCCEEDED(rv) && !exists)
407 rv = localDir->Create(nsIFile::DIRECTORY_TYPE, 0700);
408 if (NS_FAILED(rv)) return rv;
409
410 *aLocalFile = localDir;
411 NS_ADDREF(*aLocalFile);
412
413 return rv;
414}
415
416
417//----------------------------------------------------------------------------------------
418// GetDefaultUserProfileRoot - Gets the directory which contains each user profile dir
419//
420// UNIX : ~/.mozilla/
421// WIN : <Application Data folder on user's machine>\Mozilla\Profiles
422// Mac : :Documents:Mozilla:Profiles:
423//----------------------------------------------------------------------------------------
424NS_METHOD nsAppFileLocationProvider::GetDefaultUserProfileRoot(nsILocalFile **aLocalFile)
425{
426 NS_ENSURE_ARG_POINTER(aLocalFile);
427
428 nsresult rv;
429 nsCOMPtr<nsILocalFile> localDir;
430
431 rv = GetProductDirectory(getter_AddRefs(localDir));
432 if (NS_FAILED(rv)) return rv;
433
434#if defined(XP_MAC) || defined(XP_MACOSX) || defined(XP_OS2) || defined(XP_WIN)
435 // These 3 platforms share this part of the path - do them as one
436 rv = localDir->AppendRelativeNativePath(NS_LITERAL_CSTRING("Profiles"));
437 if (NS_FAILED(rv)) return rv;
438
439 PRBool exists;
440 rv = localDir->Exists(&exists);
441 if (NS_SUCCEEDED(rv) && !exists)
442 rv = localDir->Create(nsIFile::DIRECTORY_TYPE, 0775);
443 if (NS_FAILED(rv)) return rv;
444#endif
445
446 *aLocalFile = localDir;
447 NS_ADDREF(*aLocalFile);
448
449 return rv;
450}
451
452//*****************************************************************************
453// nsAppFileLocationProvider::nsIDirectoryServiceProvider2
454//*****************************************************************************
455
456class nsAppDirectoryEnumerator : public nsISimpleEnumerator
457{
458 public:
459 NS_DECL_ISUPPORTS
460
461 /**
462 * aKeyList is a null-terminated list of properties which are provided by aProvider
463 * They do not need to be publicly defined keys.
464 */
465 nsAppDirectoryEnumerator(nsIDirectoryServiceProvider *aProvider,
466 const char* aKeyList[]) :
467 mProvider(aProvider),
468 mCurrentKey(aKeyList)
469 {
470 }
471
472 NS_IMETHOD HasMoreElements(PRBool *result)
473 {
474 while (!mNext && *mCurrentKey)
475 {
476 PRBool dontCare;
477 nsCOMPtr<nsIFile> testFile;
478 (void)mProvider->GetFile(*mCurrentKey++, &dontCare, getter_AddRefs(testFile));
479 // Don't return a file which does not exist.
480 PRBool exists;
481 if (testFile && NS_SUCCEEDED(testFile->Exists(&exists)) && exists)
482 mNext = testFile;
483 }
484 *result = mNext != nsnull;
485 return NS_OK;
486 }
487
488 NS_IMETHOD GetNext(nsISupports **result)
489 {
490 NS_ENSURE_ARG_POINTER(result);
491 *result = nsnull;
492
493 PRBool hasMore;
494 HasMoreElements(&hasMore);
495 if (!hasMore)
496 return NS_ERROR_FAILURE;
497
498 *result = mNext;
499 NS_IF_ADDREF(*result);
500 mNext = nsnull;
501
502 return *result ? NS_OK : NS_ERROR_FAILURE;
503 }
504
505 // Virtual destructor since subclass nsPathsDirectoryEnumerator
506 // does not re-implement Release()
507
508 virtual ~nsAppDirectoryEnumerator()
509 {
510 }
511
512 protected:
513 nsIDirectoryServiceProvider *mProvider;
514 const char** mCurrentKey;
515 nsCOMPtr<nsIFile> mNext;
516};
517
518NS_IMPL_ISUPPORTS1(nsAppDirectoryEnumerator, nsISimpleEnumerator)
519
520/* nsPathsDirectoryEnumerator and PATH_SEPARATOR
521 * are not used on MacOS/X. */
522
523#if defined(XP_WIN) || defined(XP_OS2)/* Win32, Win16, and OS/2 */
524#define PATH_SEPARATOR ';'
525#else /*if defined(XP_UNIX) || defined(XP_BEOS)*/
526#define PATH_SEPARATOR ':'
527#endif
528
529class nsPathsDirectoryEnumerator : public nsAppDirectoryEnumerator
530{
531 public:
532 /**
533 * aKeyList is a null-terminated list.
534 * The first element is a path list.
535 * The remainder are properties provided by aProvider.
536 * They do not need to be publicly defined keys.
537 */
538 nsPathsDirectoryEnumerator(nsIDirectoryServiceProvider *aProvider,
539 const char* aKeyList[]) :
540 nsAppDirectoryEnumerator(aProvider, aKeyList+1),
541 mEndPath(aKeyList[0])
542 {
543 }
544
545 NS_IMETHOD HasMoreElements(PRBool *result)
546 {
547 if (mEndPath)
548 while (!mNext && *mEndPath)
549 {
550 const char *pathVar = mEndPath;
551 do { ++mEndPath; } while (*mEndPath && *mEndPath != PATH_SEPARATOR);
552
553 nsCOMPtr<nsILocalFile> localFile;
554 NS_NewNativeLocalFile(Substring(pathVar, mEndPath),
555 PR_TRUE,
556 getter_AddRefs(localFile));
557 if (*mEndPath == PATH_SEPARATOR)
558 ++mEndPath;
559 // Don't return a "file" (directory) which does not exist.
560 PRBool exists;
561 if (localFile &&
562 NS_SUCCEEDED(localFile->Exists(&exists)) &&
563 exists)
564 mNext = localFile;
565 }
566 if (mNext)
567 *result = PR_TRUE;
568 else
569 nsAppDirectoryEnumerator::HasMoreElements(result);
570
571 return NS_OK;
572 }
573
574 protected:
575 const char *mEndPath;
576};
577
578NS_IMETHODIMP
579nsAppFileLocationProvider::GetFiles(const char *prop, nsISimpleEnumerator **_retval)
580{
581 NS_ENSURE_ARG_POINTER(_retval);
582 *_retval = nsnull;
583 nsresult rv = NS_ERROR_FAILURE;
584
585 if (!nsCRT::strcmp(prop, NS_APP_PLUGINS_DIR_LIST))
586 {
587#if (defined(XP_MAC) || defined(XP_MACOSX)) && !defined(VBOX_MACOSX_FOLLOWS_UNIX_IO)
588 static const char* osXKeys[] = { NS_APP_PLUGINS_DIR, NS_MACOSX_USER_PLUGIN_DIR, NS_MACOSX_LOCAL_PLUGIN_DIR, nsnull };
589 static const char* os9Keys[] = { NS_APP_PLUGINS_DIR, NS_MAC_CLASSIC_PLUGIN_DIR, nsnull };
590 static const char** keys;
591
592 if (!keys) {
593 OSErr err;
594 long response;
595 err = ::Gestalt(gestaltSystemVersion, &response);
596 keys = (!err && response >= 0x00001000) ? osXKeys : os9Keys;
597 }
598
599 *_retval = new nsAppDirectoryEnumerator(this, keys);
600#else
601 static const char* keys[] = { nsnull, NS_APP_PLUGINS_DIR, nsnull };
602 if (!keys[0] && !(keys[0] = PR_GetEnv("VBOX_XPCOM_PLUGIN_PATH"))) {
603 static const char nullstr = 0;
604 keys[0] = &nullstr;
605 }
606 *_retval = new nsPathsDirectoryEnumerator(this, keys);
607#endif
608 NS_IF_ADDREF(*_retval);
609 rv = *_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
610 }
611 return rv;
612}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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