|
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
|
2 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 #include "nsAppFileLocationProvider.h" |
|
7 #include "nsAppDirectoryServiceDefs.h" |
|
8 #include "nsDirectoryServiceDefs.h" |
|
9 #include "nsIAtom.h" |
|
10 #include "nsIFile.h" |
|
11 #include "nsString.h" |
|
12 #include "nsXPIDLString.h" |
|
13 #include "nsISimpleEnumerator.h" |
|
14 #include "prenv.h" |
|
15 #include "nsCRT.h" |
|
16 #include "nsXPCOMPrivate.h" // for XPCOM_FILE_PATH_SEPARATOR |
|
17 |
|
18 #if defined(MOZ_WIDGET_COCOA) |
|
19 #include <Carbon/Carbon.h> |
|
20 #include "nsILocalFileMac.h" |
|
21 #elif defined(XP_WIN) |
|
22 #include <windows.h> |
|
23 #include <shlobj.h> |
|
24 #elif defined(XP_UNIX) |
|
25 #include <unistd.h> |
|
26 #include <stdlib.h> |
|
27 #include <sys/param.h> |
|
28 #endif |
|
29 |
|
30 |
|
31 // WARNING: These hard coded names need to go away. They need to |
|
32 // come from localizable resources |
|
33 |
|
34 #if defined(MOZ_WIDGET_COCOA) |
|
35 #define APP_REGISTRY_NAME NS_LITERAL_CSTRING("Application Registry") |
|
36 #define ESSENTIAL_FILES NS_LITERAL_CSTRING("Essential Files") |
|
37 #elif defined(XP_WIN) |
|
38 #define APP_REGISTRY_NAME NS_LITERAL_CSTRING("registry.dat") |
|
39 #else |
|
40 #define APP_REGISTRY_NAME NS_LITERAL_CSTRING("appreg") |
|
41 #endif |
|
42 |
|
43 // define default product directory |
|
44 #define DEFAULT_PRODUCT_DIR NS_LITERAL_CSTRING(MOZ_USER_DIR) |
|
45 |
|
46 // Locally defined keys used by nsAppDirectoryEnumerator |
|
47 #define NS_ENV_PLUGINS_DIR "EnvPlugins" // env var MOZ_PLUGIN_PATH |
|
48 #define NS_USER_PLUGINS_DIR "UserPlugins" |
|
49 |
|
50 #ifdef MOZ_WIDGET_COCOA |
|
51 #define NS_MACOSX_USER_PLUGIN_DIR "OSXUserPlugins" |
|
52 #define NS_MACOSX_LOCAL_PLUGIN_DIR "OSXLocalPlugins" |
|
53 #define NS_MACOSX_JAVA2_PLUGIN_DIR "OSXJavaPlugins" |
|
54 #elif XP_UNIX |
|
55 #define NS_SYSTEM_PLUGINS_DIR "SysPlugins" |
|
56 #endif |
|
57 |
|
58 #define DEFAULTS_DIR_NAME NS_LITERAL_CSTRING("defaults") |
|
59 #define DEFAULTS_PREF_DIR_NAME NS_LITERAL_CSTRING("pref") |
|
60 #define DEFAULTS_PROFILE_DIR_NAME NS_LITERAL_CSTRING("profile") |
|
61 #define RES_DIR_NAME NS_LITERAL_CSTRING("res") |
|
62 #define CHROME_DIR_NAME NS_LITERAL_CSTRING("chrome") |
|
63 #define PLUGINS_DIR_NAME NS_LITERAL_CSTRING("plugins") |
|
64 #define SEARCH_DIR_NAME NS_LITERAL_CSTRING("searchplugins") |
|
65 |
|
66 //***************************************************************************** |
|
67 // nsAppFileLocationProvider::Constructor/Destructor |
|
68 //***************************************************************************** |
|
69 |
|
70 nsAppFileLocationProvider::nsAppFileLocationProvider() |
|
71 { |
|
72 } |
|
73 |
|
74 //***************************************************************************** |
|
75 // nsAppFileLocationProvider::nsISupports |
|
76 //***************************************************************************** |
|
77 |
|
78 NS_IMPL_ISUPPORTS(nsAppFileLocationProvider, nsIDirectoryServiceProvider, nsIDirectoryServiceProvider2) |
|
79 |
|
80 //***************************************************************************** |
|
81 // nsAppFileLocationProvider::nsIDirectoryServiceProvider |
|
82 //***************************************************************************** |
|
83 |
|
84 NS_IMETHODIMP |
|
85 nsAppFileLocationProvider::GetFile(const char *prop, bool *persistent, nsIFile **_retval) |
|
86 { |
|
87 if (NS_WARN_IF(!prop)) |
|
88 return NS_ERROR_INVALID_ARG; |
|
89 |
|
90 nsCOMPtr<nsIFile> localFile; |
|
91 nsresult rv = NS_ERROR_FAILURE; |
|
92 |
|
93 *_retval = nullptr; |
|
94 *persistent = true; |
|
95 |
|
96 #ifdef MOZ_WIDGET_COCOA |
|
97 FSRef fileRef; |
|
98 nsCOMPtr<nsILocalFileMac> macFile; |
|
99 #endif |
|
100 |
|
101 if (nsCRT::strcmp(prop, NS_APP_APPLICATION_REGISTRY_DIR) == 0) |
|
102 { |
|
103 rv = GetProductDirectory(getter_AddRefs(localFile)); |
|
104 } |
|
105 else if (nsCRT::strcmp(prop, NS_APP_APPLICATION_REGISTRY_FILE) == 0) |
|
106 { |
|
107 rv = GetProductDirectory(getter_AddRefs(localFile)); |
|
108 if (NS_SUCCEEDED(rv)) |
|
109 rv = localFile->AppendNative(APP_REGISTRY_NAME); |
|
110 } |
|
111 else if (nsCRT::strcmp(prop, NS_APP_DEFAULTS_50_DIR) == 0) |
|
112 { |
|
113 rv = CloneMozBinDirectory(getter_AddRefs(localFile)); |
|
114 if (NS_SUCCEEDED(rv)) |
|
115 rv = localFile->AppendRelativeNativePath(DEFAULTS_DIR_NAME); |
|
116 } |
|
117 else if (nsCRT::strcmp(prop, NS_APP_PREF_DEFAULTS_50_DIR) == 0) |
|
118 { |
|
119 rv = CloneMozBinDirectory(getter_AddRefs(localFile)); |
|
120 if (NS_SUCCEEDED(rv)) { |
|
121 rv = localFile->AppendRelativeNativePath(DEFAULTS_DIR_NAME); |
|
122 if (NS_SUCCEEDED(rv)) |
|
123 rv = localFile->AppendRelativeNativePath(DEFAULTS_PREF_DIR_NAME); |
|
124 } |
|
125 } |
|
126 else if (nsCRT::strcmp(prop, NS_APP_PROFILE_DEFAULTS_50_DIR) == 0 || |
|
127 nsCRT::strcmp(prop, NS_APP_PROFILE_DEFAULTS_NLOC_50_DIR) == 0) |
|
128 { |
|
129 rv = CloneMozBinDirectory(getter_AddRefs(localFile)); |
|
130 if (NS_SUCCEEDED(rv)) { |
|
131 rv = localFile->AppendRelativeNativePath(DEFAULTS_DIR_NAME); |
|
132 if (NS_SUCCEEDED(rv)) |
|
133 rv = localFile->AppendRelativeNativePath(DEFAULTS_PROFILE_DIR_NAME); |
|
134 } |
|
135 } |
|
136 else if (nsCRT::strcmp(prop, NS_APP_USER_PROFILES_ROOT_DIR) == 0) |
|
137 { |
|
138 rv = GetDefaultUserProfileRoot(getter_AddRefs(localFile)); |
|
139 } |
|
140 else if (nsCRT::strcmp(prop, NS_APP_USER_PROFILES_LOCAL_ROOT_DIR) == 0) |
|
141 { |
|
142 rv = GetDefaultUserProfileRoot(getter_AddRefs(localFile), true); |
|
143 } |
|
144 else if (nsCRT::strcmp(prop, NS_APP_RES_DIR) == 0) |
|
145 { |
|
146 rv = CloneMozBinDirectory(getter_AddRefs(localFile)); |
|
147 if (NS_SUCCEEDED(rv)) |
|
148 rv = localFile->AppendRelativeNativePath(RES_DIR_NAME); |
|
149 } |
|
150 else if (nsCRT::strcmp(prop, NS_APP_CHROME_DIR) == 0) |
|
151 { |
|
152 rv = CloneMozBinDirectory(getter_AddRefs(localFile)); |
|
153 if (NS_SUCCEEDED(rv)) |
|
154 rv = localFile->AppendRelativeNativePath(CHROME_DIR_NAME); |
|
155 } |
|
156 else if (nsCRT::strcmp(prop, NS_APP_PLUGINS_DIR) == 0) |
|
157 { |
|
158 rv = CloneMozBinDirectory(getter_AddRefs(localFile)); |
|
159 if (NS_SUCCEEDED(rv)) |
|
160 rv = localFile->AppendRelativeNativePath(PLUGINS_DIR_NAME); |
|
161 } |
|
162 #ifdef MOZ_WIDGET_COCOA |
|
163 else if (nsCRT::strcmp(prop, NS_MACOSX_USER_PLUGIN_DIR) == 0) |
|
164 { |
|
165 if (::FSFindFolder(kUserDomain, kInternetPlugInFolderType, false, &fileRef) == noErr) { |
|
166 rv = NS_NewLocalFileWithFSRef(&fileRef, true, getter_AddRefs(macFile)); |
|
167 if (NS_SUCCEEDED(rv)) |
|
168 localFile = macFile; |
|
169 } |
|
170 } |
|
171 else if (nsCRT::strcmp(prop, NS_MACOSX_LOCAL_PLUGIN_DIR) == 0) |
|
172 { |
|
173 if (::FSFindFolder(kLocalDomain, kInternetPlugInFolderType, false, &fileRef) == noErr) { |
|
174 rv = NS_NewLocalFileWithFSRef(&fileRef, true, getter_AddRefs(macFile)); |
|
175 if (NS_SUCCEEDED(rv)) |
|
176 localFile = macFile; |
|
177 } |
|
178 } |
|
179 else if (nsCRT::strcmp(prop, NS_MACOSX_JAVA2_PLUGIN_DIR) == 0) |
|
180 { |
|
181 static const char *const java2PluginDirPath = |
|
182 "/System/Library/Java/Support/Deploy.bundle/Contents/Resources/"; |
|
183 rv = NS_NewNativeLocalFile(nsDependentCString(java2PluginDirPath), true, getter_AddRefs(localFile)); |
|
184 } |
|
185 #else |
|
186 else if (nsCRT::strcmp(prop, NS_ENV_PLUGINS_DIR) == 0) |
|
187 { |
|
188 NS_ERROR("Don't use nsAppFileLocationProvider::GetFile(NS_ENV_PLUGINS_DIR, ...). " |
|
189 "Use nsAppFileLocationProvider::GetFiles(...)."); |
|
190 const char *pathVar = PR_GetEnv("MOZ_PLUGIN_PATH"); |
|
191 if (pathVar && *pathVar) |
|
192 rv = NS_NewNativeLocalFile(nsDependentCString(pathVar), true, |
|
193 getter_AddRefs(localFile)); |
|
194 } |
|
195 else if (nsCRT::strcmp(prop, NS_USER_PLUGINS_DIR) == 0) |
|
196 { |
|
197 #ifdef ENABLE_SYSTEM_EXTENSION_DIRS |
|
198 rv = GetProductDirectory(getter_AddRefs(localFile)); |
|
199 if (NS_SUCCEEDED(rv)) |
|
200 rv = localFile->AppendRelativeNativePath(PLUGINS_DIR_NAME); |
|
201 #else |
|
202 rv = NS_ERROR_FAILURE; |
|
203 #endif |
|
204 } |
|
205 #ifdef XP_UNIX |
|
206 else if (nsCRT::strcmp(prop, NS_SYSTEM_PLUGINS_DIR) == 0) { |
|
207 #ifdef ENABLE_SYSTEM_EXTENSION_DIRS |
|
208 static const char *const sysLPlgDir = |
|
209 #if defined(HAVE_USR_LIB64_DIR) && defined(__LP64__) |
|
210 "/usr/lib64/mozilla/plugins"; |
|
211 #elif defined(__OpenBSD__) || defined (__FreeBSD__) |
|
212 "/usr/local/lib/mozilla/plugins"; |
|
213 #else |
|
214 "/usr/lib/mozilla/plugins"; |
|
215 #endif |
|
216 rv = NS_NewNativeLocalFile(nsDependentCString(sysLPlgDir), |
|
217 false, getter_AddRefs(localFile)); |
|
218 #else |
|
219 rv = NS_ERROR_FAILURE; |
|
220 #endif |
|
221 } |
|
222 #endif |
|
223 #endif |
|
224 else if (nsCRT::strcmp(prop, NS_APP_SEARCH_DIR) == 0) |
|
225 { |
|
226 rv = CloneMozBinDirectory(getter_AddRefs(localFile)); |
|
227 if (NS_SUCCEEDED(rv)) |
|
228 rv = localFile->AppendRelativeNativePath(SEARCH_DIR_NAME); |
|
229 } |
|
230 else if (nsCRT::strcmp(prop, NS_APP_USER_SEARCH_DIR) == 0) |
|
231 { |
|
232 rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, _retval); |
|
233 if (NS_SUCCEEDED(rv)) |
|
234 rv = (*_retval)->AppendNative(SEARCH_DIR_NAME); |
|
235 } |
|
236 else if (nsCRT::strcmp(prop, NS_APP_INSTALL_CLEANUP_DIR) == 0) |
|
237 { |
|
238 // This is cloned so that embeddors will have a hook to override |
|
239 // with their own cleanup dir. See bugzilla bug #105087 |
|
240 rv = CloneMozBinDirectory(getter_AddRefs(localFile)); |
|
241 } |
|
242 |
|
243 if (localFile && NS_SUCCEEDED(rv)) |
|
244 return localFile->QueryInterface(NS_GET_IID(nsIFile), (void**)_retval); |
|
245 |
|
246 return rv; |
|
247 } |
|
248 |
|
249 |
|
250 NS_METHOD nsAppFileLocationProvider::CloneMozBinDirectory(nsIFile **aLocalFile) |
|
251 { |
|
252 if (NS_WARN_IF(!aLocalFile)) |
|
253 return NS_ERROR_INVALID_ARG; |
|
254 nsresult rv; |
|
255 |
|
256 if (!mMozBinDirectory) |
|
257 { |
|
258 // Get the mozilla bin directory |
|
259 // 1. Check the directory service first for NS_XPCOM_CURRENT_PROCESS_DIR |
|
260 // This will be set if a directory was passed to NS_InitXPCOM |
|
261 // 2. If that doesn't work, set it to be the current process directory |
|
262 nsCOMPtr<nsIProperties> |
|
263 directoryService(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv)); |
|
264 if (NS_FAILED(rv)) |
|
265 return rv; |
|
266 |
|
267 rv = directoryService->Get(NS_XPCOM_CURRENT_PROCESS_DIR, NS_GET_IID(nsIFile), getter_AddRefs(mMozBinDirectory)); |
|
268 if (NS_FAILED(rv)) { |
|
269 rv = directoryService->Get(NS_OS_CURRENT_PROCESS_DIR, NS_GET_IID(nsIFile), getter_AddRefs(mMozBinDirectory)); |
|
270 if (NS_FAILED(rv)) |
|
271 return rv; |
|
272 } |
|
273 } |
|
274 |
|
275 nsCOMPtr<nsIFile> aFile; |
|
276 rv = mMozBinDirectory->Clone(getter_AddRefs(aFile)); |
|
277 if (NS_FAILED(rv)) |
|
278 return rv; |
|
279 |
|
280 NS_IF_ADDREF(*aLocalFile = aFile); |
|
281 return NS_OK; |
|
282 } |
|
283 |
|
284 |
|
285 //---------------------------------------------------------------------------------------- |
|
286 // GetProductDirectory - Gets the directory which contains the application data folder |
|
287 // |
|
288 // UNIX and WIN : <App Folder>/TorBrowser/Data/Browser |
|
289 // Mac : <App Folder>/../../TorBrowser/Data/Browser |
|
290 //---------------------------------------------------------------------------------------- |
|
291 NS_METHOD nsAppFileLocationProvider::GetProductDirectory(nsIFile **aLocalFile, bool aLocal) |
|
292 { |
|
293 if (NS_WARN_IF(!aLocalFile)) |
|
294 return NS_ERROR_INVALID_ARG; |
|
295 |
|
296 nsresult rv; |
|
297 bool exists; |
|
298 nsCOMPtr<nsIFile> localDir; |
|
299 |
|
300 rv = CloneMozBinDirectory(getter_AddRefs(localDir)); |
|
301 NS_ENSURE_SUCCESS(rv, rv); |
|
302 |
|
303 int levelsToRemove = 1; // In FF21+, bin dir points to browser subdirectory. |
|
304 #if defined(XP_MACOSX) |
|
305 levelsToRemove += 2; |
|
306 #endif |
|
307 while (localDir && (levelsToRemove > 0)) { |
|
308 // When crawling up the hierarchy, components named "." do not count. |
|
309 nsAutoCString removedName; |
|
310 rv = localDir->GetNativeLeafName(removedName); |
|
311 NS_ENSURE_SUCCESS(rv, rv); |
|
312 bool didRemove = !removedName.Equals("."); |
|
313 |
|
314 // Remove a directory component. |
|
315 nsCOMPtr<nsIFile> parentDir; |
|
316 rv = localDir->GetParent(getter_AddRefs(parentDir)); |
|
317 NS_ENSURE_SUCCESS(rv, rv); |
|
318 localDir = parentDir; |
|
319 |
|
320 if (didRemove) |
|
321 --levelsToRemove; |
|
322 } |
|
323 |
|
324 if (!localDir) |
|
325 return NS_ERROR_FAILURE; |
|
326 |
|
327 rv = localDir->AppendRelativeNativePath(NS_LITERAL_CSTRING("TorBrowser" |
|
328 XPCOM_FILE_PATH_SEPARATOR "Data" |
|
329 XPCOM_FILE_PATH_SEPARATOR "Browser")); |
|
330 NS_ENSURE_SUCCESS(rv, rv); |
|
331 |
|
332 if (aLocal) { |
|
333 rv = localDir->AppendNative(NS_LITERAL_CSTRING("Caches")); |
|
334 NS_ENSURE_SUCCESS(rv, rv); |
|
335 } |
|
336 |
|
337 rv = localDir->Exists(&exists); |
|
338 |
|
339 if (NS_SUCCEEDED(rv) && !exists) |
|
340 rv = localDir->Create(nsIFile::DIRECTORY_TYPE, 0700); |
|
341 |
|
342 if (NS_FAILED(rv)) return rv; |
|
343 |
|
344 *aLocalFile = localDir; |
|
345 NS_ADDREF(*aLocalFile); |
|
346 |
|
347 return rv; |
|
348 } |
|
349 |
|
350 |
|
351 //---------------------------------------------------------------------------------------- |
|
352 // GetDefaultUserProfileRoot - Gets the directory which contains each user profile dir |
|
353 //---------------------------------------------------------------------------------------- |
|
354 NS_METHOD nsAppFileLocationProvider::GetDefaultUserProfileRoot(nsIFile **aLocalFile, bool aLocal) |
|
355 { |
|
356 if (NS_WARN_IF(!aLocalFile)) |
|
357 return NS_ERROR_INVALID_ARG; |
|
358 |
|
359 nsresult rv; |
|
360 nsCOMPtr<nsIFile> localDir; |
|
361 |
|
362 rv = GetProductDirectory(getter_AddRefs(localDir), aLocal); |
|
363 if (NS_FAILED(rv)) return rv; |
|
364 |
|
365 *aLocalFile = localDir; |
|
366 NS_ADDREF(*aLocalFile); |
|
367 |
|
368 return rv; |
|
369 } |
|
370 |
|
371 //***************************************************************************** |
|
372 // nsAppFileLocationProvider::nsIDirectoryServiceProvider2 |
|
373 //***************************************************************************** |
|
374 |
|
375 class nsAppDirectoryEnumerator : public nsISimpleEnumerator |
|
376 { |
|
377 public: |
|
378 NS_DECL_ISUPPORTS |
|
379 |
|
380 /** |
|
381 * aKeyList is a null-terminated list of properties which are provided by aProvider |
|
382 * They do not need to be publicly defined keys. |
|
383 */ |
|
384 nsAppDirectoryEnumerator(nsIDirectoryServiceProvider *aProvider, |
|
385 const char* aKeyList[]) : |
|
386 mProvider(aProvider), |
|
387 mCurrentKey(aKeyList) |
|
388 { |
|
389 } |
|
390 |
|
391 NS_IMETHOD HasMoreElements(bool *result) |
|
392 { |
|
393 while (!mNext && *mCurrentKey) |
|
394 { |
|
395 bool dontCare; |
|
396 nsCOMPtr<nsIFile> testFile; |
|
397 (void)mProvider->GetFile(*mCurrentKey++, &dontCare, getter_AddRefs(testFile)); |
|
398 // Don't return a file which does not exist. |
|
399 bool exists; |
|
400 if (testFile && NS_SUCCEEDED(testFile->Exists(&exists)) && exists) |
|
401 mNext = testFile; |
|
402 } |
|
403 *result = mNext != nullptr; |
|
404 return NS_OK; |
|
405 } |
|
406 |
|
407 NS_IMETHOD GetNext(nsISupports **result) |
|
408 { |
|
409 if (NS_WARN_IF(!result)) |
|
410 return NS_ERROR_INVALID_ARG; |
|
411 *result = nullptr; |
|
412 |
|
413 bool hasMore; |
|
414 HasMoreElements(&hasMore); |
|
415 if (!hasMore) |
|
416 return NS_ERROR_FAILURE; |
|
417 |
|
418 *result = mNext; |
|
419 NS_IF_ADDREF(*result); |
|
420 mNext = nullptr; |
|
421 |
|
422 return *result ? NS_OK : NS_ERROR_FAILURE; |
|
423 } |
|
424 |
|
425 // Virtual destructor since subclass nsPathsDirectoryEnumerator |
|
426 // does not re-implement Release() |
|
427 |
|
428 virtual ~nsAppDirectoryEnumerator() |
|
429 { |
|
430 } |
|
431 |
|
432 protected: |
|
433 nsIDirectoryServiceProvider *mProvider; |
|
434 const char** mCurrentKey; |
|
435 nsCOMPtr<nsIFile> mNext; |
|
436 }; |
|
437 |
|
438 NS_IMPL_ISUPPORTS(nsAppDirectoryEnumerator, nsISimpleEnumerator) |
|
439 |
|
440 /* nsPathsDirectoryEnumerator and PATH_SEPARATOR |
|
441 * are not used on MacOS/X. */ |
|
442 |
|
443 #if defined(XP_WIN) /* Win32 */ |
|
444 #define PATH_SEPARATOR ';' |
|
445 #else |
|
446 #define PATH_SEPARATOR ':' |
|
447 #endif |
|
448 |
|
449 class nsPathsDirectoryEnumerator : public nsAppDirectoryEnumerator |
|
450 { |
|
451 public: |
|
452 /** |
|
453 * aKeyList is a null-terminated list. |
|
454 * The first element is a path list. |
|
455 * The remainder are properties provided by aProvider. |
|
456 * They do not need to be publicly defined keys. |
|
457 */ |
|
458 nsPathsDirectoryEnumerator(nsIDirectoryServiceProvider *aProvider, |
|
459 const char* aKeyList[]) : |
|
460 nsAppDirectoryEnumerator(aProvider, aKeyList+1), |
|
461 mEndPath(aKeyList[0]) |
|
462 { |
|
463 } |
|
464 |
|
465 NS_IMETHOD HasMoreElements(bool *result) |
|
466 { |
|
467 if (mEndPath) |
|
468 while (!mNext && *mEndPath) |
|
469 { |
|
470 const char *pathVar = mEndPath; |
|
471 |
|
472 // skip PATH_SEPARATORs at the begining of the mEndPath |
|
473 while (*pathVar == PATH_SEPARATOR) pathVar++; |
|
474 |
|
475 do { ++mEndPath; } while (*mEndPath && *mEndPath != PATH_SEPARATOR); |
|
476 |
|
477 nsCOMPtr<nsIFile> localFile; |
|
478 NS_NewNativeLocalFile(Substring(pathVar, mEndPath), |
|
479 true, |
|
480 getter_AddRefs(localFile)); |
|
481 if (*mEndPath == PATH_SEPARATOR) |
|
482 ++mEndPath; |
|
483 // Don't return a "file" (directory) which does not exist. |
|
484 bool exists; |
|
485 if (localFile && |
|
486 NS_SUCCEEDED(localFile->Exists(&exists)) && |
|
487 exists) |
|
488 mNext = localFile; |
|
489 } |
|
490 if (mNext) |
|
491 *result = true; |
|
492 else |
|
493 nsAppDirectoryEnumerator::HasMoreElements(result); |
|
494 |
|
495 return NS_OK; |
|
496 } |
|
497 |
|
498 protected: |
|
499 const char *mEndPath; |
|
500 }; |
|
501 |
|
502 NS_IMETHODIMP |
|
503 nsAppFileLocationProvider::GetFiles(const char *prop, nsISimpleEnumerator **_retval) |
|
504 { |
|
505 if (NS_WARN_IF(!_retval)) |
|
506 return NS_ERROR_INVALID_ARG; |
|
507 *_retval = nullptr; |
|
508 nsresult rv = NS_ERROR_FAILURE; |
|
509 |
|
510 if (!nsCRT::strcmp(prop, NS_APP_PLUGINS_DIR_LIST)) |
|
511 { |
|
512 #ifdef MOZ_WIDGET_COCOA |
|
513 // As of Java for Mac OS X 10.5 Update 10, Apple has (in effect) deprecated Java Plugin2 on |
|
514 // on OS X 10.5, and removed the soft link to it from /Library/Internet Plug-Ins/. Java |
|
515 // Plugin2 is still present and usable, but there are no longer any links to it in the |
|
516 // "normal" locations. So we won't be able to find it unless we look in the "non-normal" |
|
517 // location where it actually is. Safari can use the WebKit-specific JavaPluginCocoa.bundle, |
|
518 // which (of course) is still fully supported on OS X 10.5. But we have no alternative to |
|
519 // using Java Plugin2. For more information see bug 668639. |
|
520 static const char* keys[] = { NS_APP_PLUGINS_DIR, NS_MACOSX_USER_PLUGIN_DIR, |
|
521 NS_MACOSX_LOCAL_PLUGIN_DIR, |
|
522 IsOSXLeopard() ? NS_MACOSX_JAVA2_PLUGIN_DIR : nullptr, nullptr }; |
|
523 *_retval = new nsAppDirectoryEnumerator(this, keys); |
|
524 #else |
|
525 #ifdef XP_UNIX |
|
526 static const char* keys[] = { nullptr, NS_USER_PLUGINS_DIR, NS_APP_PLUGINS_DIR, NS_SYSTEM_PLUGINS_DIR, nullptr }; |
|
527 #else |
|
528 static const char* keys[] = { nullptr, NS_USER_PLUGINS_DIR, NS_APP_PLUGINS_DIR, nullptr }; |
|
529 #endif |
|
530 if (!keys[0] && !(keys[0] = PR_GetEnv("MOZ_PLUGIN_PATH"))) { |
|
531 static const char nullstr = 0; |
|
532 keys[0] = &nullstr; |
|
533 } |
|
534 *_retval = new nsPathsDirectoryEnumerator(this, keys); |
|
535 #endif |
|
536 NS_IF_ADDREF(*_retval); |
|
537 rv = *_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY; |
|
538 } |
|
539 if (!nsCRT::strcmp(prop, NS_APP_SEARCH_DIR_LIST)) |
|
540 { |
|
541 static const char* keys[] = { nullptr, NS_APP_SEARCH_DIR, NS_APP_USER_SEARCH_DIR, nullptr }; |
|
542 if (!keys[0] && !(keys[0] = PR_GetEnv("MOZ_SEARCH_ENGINE_PATH"))) { |
|
543 static const char nullstr = 0; |
|
544 keys[0] = &nullstr; |
|
545 } |
|
546 *_retval = new nsPathsDirectoryEnumerator(this, keys); |
|
547 NS_IF_ADDREF(*_retval); |
|
548 rv = *_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY; |
|
549 } |
|
550 return rv; |
|
551 } |
|
552 |
|
553 #if defined(MOZ_WIDGET_COCOA) |
|
554 bool |
|
555 nsAppFileLocationProvider::IsOSXLeopard() |
|
556 { |
|
557 static SInt32 version = 0; |
|
558 |
|
559 if (!version) { |
|
560 OSErr err = ::Gestalt(gestaltSystemVersion, &version); |
|
561 if (err != noErr) { |
|
562 version = 0; |
|
563 } else { |
|
564 version &= 0xFFFF; // The system version is in the low order word |
|
565 } |
|
566 } |
|
567 |
|
568 return ((version >= 0x1050) && (version < 0x1060)); |
|
569 } |
|
570 #endif |