VirtualBox

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

最後變更 在這個檔案從65902是 46043,由 vboxsync 提交於 12 年 前

src/libs/xpcom18a4: remove L4.

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 21.8 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(XP_UNIX)
382 rv = NS_NewNativeLocalFile(nsDependentCString(PR_GetEnv("HOME")), PR_TRUE, getter_AddRefs(localDir));
383 if (NS_FAILED(rv)) return rv;
384#elif defined(XP_BEOS)
385 char path[MAXPATHLEN];
386 find_directory(B_USER_SETTINGS_DIRECTORY, 0, 0, path, MAXPATHLEN);
387 // Need enough space to add the trailing backslash
388 int len = strlen(path);
389 if (len > MAXPATHLEN-2)
390 return NS_ERROR_FAILURE;
391 path[len] = '/';
392 path[len+1] = '\0';
393 rv = NS_NewNativeLocalFile(nsDependentCString(path), PR_TRUE, getter_AddRefs(localDir));
394 if (NS_FAILED(rv)) return rv;
395#else
396#error dont_know_how_to_get_product_dir_on_your_platform
397#endif
398
399 rv = localDir->AppendRelativeNativePath(DEFAULT_PRODUCT_DIR);
400 if (NS_FAILED(rv)) return rv;
401 rv = localDir->Exists(&exists);
402 if (NS_SUCCEEDED(rv) && !exists)
403 rv = localDir->Create(nsIFile::DIRECTORY_TYPE, 0700);
404 if (NS_FAILED(rv)) return rv;
405
406 *aLocalFile = localDir;
407 NS_ADDREF(*aLocalFile);
408
409 return rv;
410}
411
412
413//----------------------------------------------------------------------------------------
414// GetDefaultUserProfileRoot - Gets the directory which contains each user profile dir
415//
416// UNIX : ~/.mozilla/
417// WIN : <Application Data folder on user's machine>\Mozilla\Profiles
418// Mac : :Documents:Mozilla:Profiles:
419//----------------------------------------------------------------------------------------
420NS_METHOD nsAppFileLocationProvider::GetDefaultUserProfileRoot(nsILocalFile **aLocalFile)
421{
422 NS_ENSURE_ARG_POINTER(aLocalFile);
423
424 nsresult rv;
425 nsCOMPtr<nsILocalFile> localDir;
426
427 rv = GetProductDirectory(getter_AddRefs(localDir));
428 if (NS_FAILED(rv)) return rv;
429
430#if defined(XP_MAC) || defined(XP_MACOSX) || defined(XP_OS2) || defined(XP_WIN)
431 // These 3 platforms share this part of the path - do them as one
432 rv = localDir->AppendRelativeNativePath(NS_LITERAL_CSTRING("Profiles"));
433 if (NS_FAILED(rv)) return rv;
434
435 PRBool exists;
436 rv = localDir->Exists(&exists);
437 if (NS_SUCCEEDED(rv) && !exists)
438 rv = localDir->Create(nsIFile::DIRECTORY_TYPE, 0775);
439 if (NS_FAILED(rv)) return rv;
440#endif
441
442 *aLocalFile = localDir;
443 NS_ADDREF(*aLocalFile);
444
445 return rv;
446}
447
448//*****************************************************************************
449// nsAppFileLocationProvider::nsIDirectoryServiceProvider2
450//*****************************************************************************
451
452class nsAppDirectoryEnumerator : public nsISimpleEnumerator
453{
454 public:
455 NS_DECL_ISUPPORTS
456
457 /**
458 * aKeyList is a null-terminated list of properties which are provided by aProvider
459 * They do not need to be publicly defined keys.
460 */
461 nsAppDirectoryEnumerator(nsIDirectoryServiceProvider *aProvider,
462 const char* aKeyList[]) :
463 mProvider(aProvider),
464 mCurrentKey(aKeyList)
465 {
466 }
467
468 NS_IMETHOD HasMoreElements(PRBool *result)
469 {
470 while (!mNext && *mCurrentKey)
471 {
472 PRBool dontCare;
473 nsCOMPtr<nsIFile> testFile;
474 (void)mProvider->GetFile(*mCurrentKey++, &dontCare, getter_AddRefs(testFile));
475 // Don't return a file which does not exist.
476 PRBool exists;
477 if (testFile && NS_SUCCEEDED(testFile->Exists(&exists)) && exists)
478 mNext = testFile;
479 }
480 *result = mNext != nsnull;
481 return NS_OK;
482 }
483
484 NS_IMETHOD GetNext(nsISupports **result)
485 {
486 NS_ENSURE_ARG_POINTER(result);
487 *result = nsnull;
488
489 PRBool hasMore;
490 HasMoreElements(&hasMore);
491 if (!hasMore)
492 return NS_ERROR_FAILURE;
493
494 *result = mNext;
495 NS_IF_ADDREF(*result);
496 mNext = nsnull;
497
498 return *result ? NS_OK : NS_ERROR_FAILURE;
499 }
500
501 // Virtual destructor since subclass nsPathsDirectoryEnumerator
502 // does not re-implement Release()
503
504 virtual ~nsAppDirectoryEnumerator()
505 {
506 }
507
508 protected:
509 nsIDirectoryServiceProvider *mProvider;
510 const char** mCurrentKey;
511 nsCOMPtr<nsIFile> mNext;
512};
513
514NS_IMPL_ISUPPORTS1(nsAppDirectoryEnumerator, nsISimpleEnumerator)
515
516/* nsPathsDirectoryEnumerator and PATH_SEPARATOR
517 * are not used on MacOS/X. */
518
519#if defined(XP_WIN) || defined(XP_OS2)/* Win32, Win16, and OS/2 */
520#define PATH_SEPARATOR ';'
521#else /*if defined(XP_UNIX) || defined(XP_BEOS)*/
522#define PATH_SEPARATOR ':'
523#endif
524
525class nsPathsDirectoryEnumerator : public nsAppDirectoryEnumerator
526{
527 public:
528 /**
529 * aKeyList is a null-terminated list.
530 * The first element is a path list.
531 * The remainder are properties provided by aProvider.
532 * They do not need to be publicly defined keys.
533 */
534 nsPathsDirectoryEnumerator(nsIDirectoryServiceProvider *aProvider,
535 const char* aKeyList[]) :
536 nsAppDirectoryEnumerator(aProvider, aKeyList+1),
537 mEndPath(aKeyList[0])
538 {
539 }
540
541 NS_IMETHOD HasMoreElements(PRBool *result)
542 {
543 if (mEndPath)
544 while (!mNext && *mEndPath)
545 {
546 const char *pathVar = mEndPath;
547 do { ++mEndPath; } while (*mEndPath && *mEndPath != PATH_SEPARATOR);
548
549 nsCOMPtr<nsILocalFile> localFile;
550 NS_NewNativeLocalFile(Substring(pathVar, mEndPath),
551 PR_TRUE,
552 getter_AddRefs(localFile));
553 if (*mEndPath == PATH_SEPARATOR)
554 ++mEndPath;
555 // Don't return a "file" (directory) which does not exist.
556 PRBool exists;
557 if (localFile &&
558 NS_SUCCEEDED(localFile->Exists(&exists)) &&
559 exists)
560 mNext = localFile;
561 }
562 if (mNext)
563 *result = PR_TRUE;
564 else
565 nsAppDirectoryEnumerator::HasMoreElements(result);
566
567 return NS_OK;
568 }
569
570 protected:
571 const char *mEndPath;
572};
573
574NS_IMETHODIMP
575nsAppFileLocationProvider::GetFiles(const char *prop, nsISimpleEnumerator **_retval)
576{
577 NS_ENSURE_ARG_POINTER(_retval);
578 *_retval = nsnull;
579 nsresult rv = NS_ERROR_FAILURE;
580
581 if (!nsCRT::strcmp(prop, NS_APP_PLUGINS_DIR_LIST))
582 {
583#if (defined(XP_MAC) || defined(XP_MACOSX)) && !defined(VBOX_MACOSX_FOLLOWS_UNIX_IO)
584 static const char* osXKeys[] = { NS_APP_PLUGINS_DIR, NS_MACOSX_USER_PLUGIN_DIR, NS_MACOSX_LOCAL_PLUGIN_DIR, nsnull };
585 static const char* os9Keys[] = { NS_APP_PLUGINS_DIR, NS_MAC_CLASSIC_PLUGIN_DIR, nsnull };
586 static const char** keys;
587
588 if (!keys) {
589 OSErr err;
590 long response;
591 err = ::Gestalt(gestaltSystemVersion, &response);
592 keys = (!err && response >= 0x00001000) ? osXKeys : os9Keys;
593 }
594
595 *_retval = new nsAppDirectoryEnumerator(this, keys);
596#else
597 static const char* keys[] = { nsnull, NS_APP_PLUGINS_DIR, nsnull };
598 if (!keys[0] && !(keys[0] = PR_GetEnv("VBOX_XPCOM_PLUGIN_PATH"))) {
599 static const char nullstr = 0;
600 keys[0] = &nullstr;
601 }
602 *_retval = new nsPathsDirectoryEnumerator(this, keys);
603#endif
604 NS_IF_ADDREF(*_retval);
605 rv = *_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
606 }
607 return rv;
608}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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