/src/mozilla-central/xpcom/io/nsAppFileLocationProvider.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 | | /* vim: set ts=8 sts=2 et sw=2 tw=80: */ |
3 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
4 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
5 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
6 | | |
7 | | #include "nsAppFileLocationProvider.h" |
8 | | #include "nsAppDirectoryServiceDefs.h" |
9 | | #include "nsDirectoryServiceDefs.h" |
10 | | #include "nsEnumeratorUtils.h" |
11 | | #include "nsAtom.h" |
12 | | #include "nsIFile.h" |
13 | | #include "nsString.h" |
14 | | #include "nsSimpleEnumerator.h" |
15 | | #include "prenv.h" |
16 | | #include "nsCRT.h" |
17 | | #if defined(MOZ_WIDGET_COCOA) |
18 | | #include <Carbon/Carbon.h> |
19 | | #include "nsILocalFileMac.h" |
20 | | #elif defined(XP_WIN) |
21 | | #include <windows.h> |
22 | | #include <shlobj.h> |
23 | | #elif defined(XP_UNIX) |
24 | | #include <unistd.h> |
25 | | #include <stdlib.h> |
26 | | #include <sys/param.h> |
27 | | #endif |
28 | | |
29 | | |
30 | | // WARNING: These hard coded names need to go away. They need to |
31 | | // come from localizable resources |
32 | | |
33 | | #if defined(MOZ_WIDGET_COCOA) |
34 | | #define APP_REGISTRY_NAME NS_LITERAL_CSTRING("Application Registry") |
35 | | #define ESSENTIAL_FILES NS_LITERAL_CSTRING("Essential Files") |
36 | | #elif defined(XP_WIN) |
37 | | #define APP_REGISTRY_NAME NS_LITERAL_CSTRING("registry.dat") |
38 | | #else |
39 | 0 | #define APP_REGISTRY_NAME NS_LITERAL_CSTRING("appreg") |
40 | | #endif |
41 | | |
42 | | // define default product directory |
43 | 0 | #define DEFAULT_PRODUCT_DIR NS_LITERAL_CSTRING(MOZ_USER_DIR) |
44 | | |
45 | | // Locally defined keys used by nsAppDirectoryEnumerator |
46 | 30 | #define NS_ENV_PLUGINS_DIR "EnvPlugins" // env var MOZ_PLUGIN_PATH |
47 | 30 | #define NS_USER_PLUGINS_DIR "UserPlugins" |
48 | | |
49 | | #ifdef MOZ_WIDGET_COCOA |
50 | | #define NS_MACOSX_USER_PLUGIN_DIR "OSXUserPlugins" |
51 | | #define NS_MACOSX_LOCAL_PLUGIN_DIR "OSXLocalPlugins" |
52 | | #elif XP_UNIX |
53 | 30 | #define NS_SYSTEM_PLUGINS_DIR "SysPlugins" |
54 | | #endif |
55 | | |
56 | 3 | #define DEFAULTS_DIR_NAME NS_LITERAL_CSTRING("defaults") |
57 | 3 | #define DEFAULTS_PREF_DIR_NAME NS_LITERAL_CSTRING("pref") |
58 | 0 | #define RES_DIR_NAME NS_LITERAL_CSTRING("res") |
59 | 0 | #define CHROME_DIR_NAME NS_LITERAL_CSTRING("chrome") |
60 | 0 | #define PLUGINS_DIR_NAME NS_LITERAL_CSTRING("plugins") |
61 | | |
62 | | //***************************************************************************** |
63 | | // nsAppFileLocationProvider::Constructor/Destructor |
64 | | //***************************************************************************** |
65 | | |
66 | | nsAppFileLocationProvider::nsAppFileLocationProvider() |
67 | 3 | { |
68 | 3 | } |
69 | | |
70 | | //***************************************************************************** |
71 | | // nsAppFileLocationProvider::nsISupports |
72 | | //***************************************************************************** |
73 | | |
74 | | NS_IMPL_ISUPPORTS(nsAppFileLocationProvider, |
75 | | nsIDirectoryServiceProvider, |
76 | | nsIDirectoryServiceProvider2) |
77 | | |
78 | | //***************************************************************************** |
79 | | // nsAppFileLocationProvider::nsIDirectoryServiceProvider |
80 | | //***************************************************************************** |
81 | | |
82 | | NS_IMETHODIMP |
83 | | nsAppFileLocationProvider::GetFile(const char* aProp, bool* aPersistent, |
84 | | nsIFile** aResult) |
85 | 33 | { |
86 | 33 | if (NS_WARN_IF(!aProp)) { |
87 | 0 | return NS_ERROR_INVALID_ARG; |
88 | 0 | } |
89 | 33 | |
90 | 33 | nsCOMPtr<nsIFile> localFile; |
91 | 33 | nsresult rv = NS_ERROR_FAILURE; |
92 | 33 | |
93 | 33 | *aResult = nullptr; |
94 | 33 | *aPersistent = true; |
95 | 33 | |
96 | | #ifdef MOZ_WIDGET_COCOA |
97 | | FSRef fileRef; |
98 | | nsCOMPtr<nsILocalFileMac> macFile; |
99 | | #endif |
100 | | |
101 | 33 | if (nsCRT::strcmp(aProp, NS_APP_APPLICATION_REGISTRY_DIR) == 0) { |
102 | 0 | rv = GetProductDirectory(getter_AddRefs(localFile)); |
103 | 33 | } else if (nsCRT::strcmp(aProp, NS_APP_APPLICATION_REGISTRY_FILE) == 0) { |
104 | 0 | rv = GetProductDirectory(getter_AddRefs(localFile)); |
105 | 0 | if (NS_SUCCEEDED(rv)) { |
106 | 0 | rv = localFile->AppendNative(APP_REGISTRY_NAME); |
107 | 0 | } |
108 | 33 | } else if (nsCRT::strcmp(aProp, NS_APP_DEFAULTS_50_DIR) == 0) { |
109 | 0 | rv = CloneMozBinDirectory(getter_AddRefs(localFile)); |
110 | 0 | if (NS_SUCCEEDED(rv)) { |
111 | 0 | rv = localFile->AppendRelativeNativePath(DEFAULTS_DIR_NAME); |
112 | 0 | } |
113 | 33 | } else if (nsCRT::strcmp(aProp, NS_APP_PREF_DEFAULTS_50_DIR) == 0) { |
114 | 3 | rv = CloneMozBinDirectory(getter_AddRefs(localFile)); |
115 | 3 | if (NS_SUCCEEDED(rv)) { |
116 | 3 | rv = localFile->AppendRelativeNativePath(DEFAULTS_DIR_NAME); |
117 | 3 | if (NS_SUCCEEDED(rv)) { |
118 | 3 | rv = localFile->AppendRelativeNativePath(DEFAULTS_PREF_DIR_NAME); |
119 | 3 | } |
120 | 3 | } |
121 | 30 | } else if (nsCRT::strcmp(aProp, NS_APP_USER_PROFILES_ROOT_DIR) == 0) { |
122 | 0 | rv = GetDefaultUserProfileRoot(getter_AddRefs(localFile)); |
123 | 30 | } else if (nsCRT::strcmp(aProp, NS_APP_USER_PROFILES_LOCAL_ROOT_DIR) == 0) { |
124 | 0 | rv = GetDefaultUserProfileRoot(getter_AddRefs(localFile), true); |
125 | 30 | } else if (nsCRT::strcmp(aProp, NS_APP_RES_DIR) == 0) { |
126 | 0 | rv = CloneMozBinDirectory(getter_AddRefs(localFile)); |
127 | 0 | if (NS_SUCCEEDED(rv)) { |
128 | 0 | rv = localFile->AppendRelativeNativePath(RES_DIR_NAME); |
129 | 0 | } |
130 | 30 | } else if (nsCRT::strcmp(aProp, NS_APP_CHROME_DIR) == 0) { |
131 | 0 | rv = CloneMozBinDirectory(getter_AddRefs(localFile)); |
132 | 0 | if (NS_SUCCEEDED(rv)) { |
133 | 0 | rv = localFile->AppendRelativeNativePath(CHROME_DIR_NAME); |
134 | 0 | } |
135 | 30 | } else if (nsCRT::strcmp(aProp, NS_APP_PLUGINS_DIR) == 0) { |
136 | 0 | rv = CloneMozBinDirectory(getter_AddRefs(localFile)); |
137 | 0 | if (NS_SUCCEEDED(rv)) { |
138 | 0 | rv = localFile->AppendRelativeNativePath(PLUGINS_DIR_NAME); |
139 | 0 | } |
140 | 0 | } |
141 | | #ifdef MOZ_WIDGET_COCOA |
142 | | else if (nsCRT::strcmp(aProp, NS_MACOSX_USER_PLUGIN_DIR) == 0) { |
143 | | if (::FSFindFolder(kUserDomain, kInternetPlugInFolderType, false, |
144 | | &fileRef) == noErr) { |
145 | | rv = NS_NewLocalFileWithFSRef(&fileRef, true, getter_AddRefs(macFile)); |
146 | | if (NS_SUCCEEDED(rv)) { |
147 | | localFile = macFile; |
148 | | } |
149 | | } |
150 | | } else if (nsCRT::strcmp(aProp, NS_MACOSX_LOCAL_PLUGIN_DIR) == 0) { |
151 | | if (::FSFindFolder(kLocalDomain, kInternetPlugInFolderType, false, |
152 | | &fileRef) == noErr) { |
153 | | rv = NS_NewLocalFileWithFSRef(&fileRef, true, getter_AddRefs(macFile)); |
154 | | if (NS_SUCCEEDED(rv)) { |
155 | | localFile = macFile; |
156 | | } |
157 | | } |
158 | | } |
159 | | #else |
160 | 30 | else if (nsCRT::strcmp(aProp, NS_ENV_PLUGINS_DIR) == 0) { |
161 | 0 | NS_ERROR("Don't use nsAppFileLocationProvider::GetFile(NS_ENV_PLUGINS_DIR, ...). " |
162 | 0 | "Use nsAppFileLocationProvider::GetFiles(...)."); |
163 | 0 | const char* pathVar = PR_GetEnv("MOZ_PLUGIN_PATH"); |
164 | 0 | if (pathVar && *pathVar) |
165 | 0 | rv = NS_NewNativeLocalFile(nsDependentCString(pathVar), true, |
166 | 0 | getter_AddRefs(localFile)); |
167 | 30 | } else if (nsCRT::strcmp(aProp, NS_USER_PLUGINS_DIR) == 0) { |
168 | 0 | #ifdef ENABLE_SYSTEM_EXTENSION_DIRS |
169 | 0 | rv = GetProductDirectory(getter_AddRefs(localFile)); |
170 | 0 | if (NS_SUCCEEDED(rv)) { |
171 | 0 | rv = localFile->AppendRelativeNativePath(PLUGINS_DIR_NAME); |
172 | 0 | } |
173 | | #else |
174 | | rv = NS_ERROR_FAILURE; |
175 | | #endif |
176 | | } |
177 | 30 | #ifdef XP_UNIX |
178 | 30 | else if (nsCRT::strcmp(aProp, NS_SYSTEM_PLUGINS_DIR) == 0) { |
179 | 0 | #ifdef ENABLE_SYSTEM_EXTENSION_DIRS |
180 | 0 | static const char* const sysLPlgDir = |
181 | | #if defined(HAVE_USR_LIB64_DIR) && defined(__LP64__) |
182 | | "/usr/lib64/mozilla/plugins"; |
183 | | #elif defined(__OpenBSD__) || defined (__FreeBSD__) |
184 | | "/usr/local/lib/mozilla/plugins"; |
185 | | #else |
186 | | "/usr/lib/mozilla/plugins"; |
187 | 0 | #endif |
188 | 0 | rv = NS_NewNativeLocalFile(nsDependentCString(sysLPlgDir), |
189 | 0 | false, getter_AddRefs(localFile)); |
190 | | #else |
191 | | rv = NS_ERROR_FAILURE; |
192 | | #endif |
193 | | } |
194 | 30 | #endif |
195 | 30 | #endif |
196 | 30 | else if (nsCRT::strcmp(aProp, NS_APP_INSTALL_CLEANUP_DIR) == 0) { |
197 | 0 | // This is cloned so that embeddors will have a hook to override |
198 | 0 | // with their own cleanup dir. See bugzilla bug #105087 |
199 | 0 | rv = CloneMozBinDirectory(getter_AddRefs(localFile)); |
200 | 0 | } |
201 | 33 | |
202 | 33 | if (localFile && NS_SUCCEEDED(rv)) { |
203 | 3 | localFile.forget(aResult); |
204 | 3 | return NS_OK; |
205 | 3 | } |
206 | 30 | |
207 | 30 | return rv; |
208 | 30 | } |
209 | | |
210 | | |
211 | | nsresult |
212 | | nsAppFileLocationProvider::CloneMozBinDirectory(nsIFile** aLocalFile) |
213 | 3 | { |
214 | 3 | if (NS_WARN_IF(!aLocalFile)) { |
215 | 0 | return NS_ERROR_INVALID_ARG; |
216 | 0 | } |
217 | 3 | nsresult rv; |
218 | 3 | |
219 | 3 | if (!mMozBinDirectory) { |
220 | 3 | // Get the mozilla bin directory |
221 | 3 | // 1. Check the directory service first for NS_XPCOM_CURRENT_PROCESS_DIR |
222 | 3 | // This will be set if a directory was passed to NS_InitXPCOM |
223 | 3 | // 2. If that doesn't work, set it to be the current process directory |
224 | 3 | nsCOMPtr<nsIProperties> |
225 | 3 | directoryService(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv)); |
226 | 3 | if (NS_FAILED(rv)) { |
227 | 0 | return rv; |
228 | 0 | } |
229 | 3 | |
230 | 3 | rv = directoryService->Get(NS_XPCOM_CURRENT_PROCESS_DIR, NS_GET_IID(nsIFile), |
231 | 3 | getter_AddRefs(mMozBinDirectory)); |
232 | 3 | if (NS_FAILED(rv)) { |
233 | 0 | rv = directoryService->Get(NS_OS_CURRENT_PROCESS_DIR, NS_GET_IID(nsIFile), |
234 | 0 | getter_AddRefs(mMozBinDirectory)); |
235 | 0 | if (NS_FAILED(rv)) { |
236 | 0 | return rv; |
237 | 0 | } |
238 | 3 | } |
239 | 3 | } |
240 | 3 | |
241 | 3 | nsCOMPtr<nsIFile> aFile; |
242 | 3 | rv = mMozBinDirectory->Clone(getter_AddRefs(aFile)); |
243 | 3 | if (NS_FAILED(rv)) { |
244 | 0 | return rv; |
245 | 0 | } |
246 | 3 | |
247 | 3 | NS_IF_ADDREF(*aLocalFile = aFile); |
248 | 3 | return NS_OK; |
249 | 3 | } |
250 | | |
251 | | |
252 | | //---------------------------------------------------------------------------------------- |
253 | | // GetProductDirectory - Gets the directory which contains the application data folder |
254 | | // |
255 | | // UNIX : ~/.mozilla/ |
256 | | // WIN : <Application Data folder on user's machine>\Mozilla |
257 | | // Mac : :Documents:Mozilla: |
258 | | //---------------------------------------------------------------------------------------- |
259 | | nsresult |
260 | | nsAppFileLocationProvider::GetProductDirectory(nsIFile** aLocalFile, |
261 | | bool aLocal) |
262 | 0 | { |
263 | 0 | if (NS_WARN_IF(!aLocalFile)) { |
264 | 0 | return NS_ERROR_INVALID_ARG; |
265 | 0 | } |
266 | 0 | |
267 | 0 | nsresult rv; |
268 | 0 | bool exists; |
269 | 0 | nsCOMPtr<nsIFile> localDir; |
270 | 0 |
|
271 | | #if defined(MOZ_WIDGET_COCOA) |
272 | | FSRef fsRef; |
273 | | OSType folderType = aLocal ? (OSType)kCachedDataFolderType : |
274 | | (OSType)kDomainLibraryFolderType; |
275 | | OSErr err = ::FSFindFolder(kUserDomain, folderType, kCreateFolder, &fsRef); |
276 | | if (err) { |
277 | | return NS_ERROR_FAILURE; |
278 | | } |
279 | | NS_NewLocalFile(EmptyString(), true, getter_AddRefs(localDir)); |
280 | | if (!localDir) { |
281 | | return NS_ERROR_FAILURE; |
282 | | } |
283 | | nsCOMPtr<nsILocalFileMac> localDirMac(do_QueryInterface(localDir)); |
284 | | rv = localDirMac->InitWithFSRef(&fsRef); |
285 | | if (NS_FAILED(rv)) { |
286 | | return rv; |
287 | | } |
288 | | #elif defined(XP_WIN) |
289 | | nsCOMPtr<nsIProperties> directoryService = |
290 | | do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv); |
291 | | if (NS_FAILED(rv)) { |
292 | | return rv; |
293 | | } |
294 | | const char* prop = aLocal ? NS_WIN_LOCAL_APPDATA_DIR : NS_WIN_APPDATA_DIR; |
295 | | rv = directoryService->Get(prop, NS_GET_IID(nsIFile), getter_AddRefs(localDir)); |
296 | | if (NS_FAILED(rv)) { |
297 | | return rv; |
298 | | } |
299 | | #elif defined(XP_UNIX) |
300 | | rv = NS_NewNativeLocalFile(nsDependentCString(PR_GetEnv("HOME")), true, |
301 | 0 | getter_AddRefs(localDir)); |
302 | 0 | if (NS_FAILED(rv)) { |
303 | 0 | return rv; |
304 | 0 | } |
305 | | #else |
306 | | #error dont_know_how_to_get_product_dir_on_your_platform |
307 | | #endif |
308 | | |
309 | 0 | rv = localDir->AppendRelativeNativePath(DEFAULT_PRODUCT_DIR); |
310 | 0 | if (NS_FAILED(rv)) { |
311 | 0 | return rv; |
312 | 0 | } |
313 | 0 | rv = localDir->Exists(&exists); |
314 | 0 |
|
315 | 0 | if (NS_SUCCEEDED(rv) && !exists) { |
316 | 0 | rv = localDir->Create(nsIFile::DIRECTORY_TYPE, 0700); |
317 | 0 | } |
318 | 0 |
|
319 | 0 | if (NS_FAILED(rv)) { |
320 | 0 | return rv; |
321 | 0 | } |
322 | 0 | |
323 | 0 | localDir.forget(aLocalFile); |
324 | 0 |
|
325 | 0 | return rv; |
326 | 0 | } |
327 | | |
328 | | |
329 | | //---------------------------------------------------------------------------------------- |
330 | | // GetDefaultUserProfileRoot - Gets the directory which contains each user profile dir |
331 | | // |
332 | | // UNIX : ~/.mozilla/ |
333 | | // WIN : <Application Data folder on user's machine>\Mozilla\Profiles |
334 | | // Mac : :Documents:Mozilla:Profiles: |
335 | | //---------------------------------------------------------------------------------------- |
336 | | nsresult |
337 | | nsAppFileLocationProvider::GetDefaultUserProfileRoot(nsIFile** aLocalFile, |
338 | | bool aLocal) |
339 | 0 | { |
340 | 0 | if (NS_WARN_IF(!aLocalFile)) { |
341 | 0 | return NS_ERROR_INVALID_ARG; |
342 | 0 | } |
343 | 0 | |
344 | 0 | nsresult rv; |
345 | 0 | nsCOMPtr<nsIFile> localDir; |
346 | 0 |
|
347 | 0 | rv = GetProductDirectory(getter_AddRefs(localDir), aLocal); |
348 | 0 | if (NS_FAILED(rv)) { |
349 | 0 | return rv; |
350 | 0 | } |
351 | 0 | |
352 | | #if defined(MOZ_WIDGET_COCOA) || defined(XP_WIN) |
353 | | // These 3 platforms share this part of the path - do them as one |
354 | | rv = localDir->AppendRelativeNativePath(NS_LITERAL_CSTRING("Profiles")); |
355 | | if (NS_FAILED(rv)) { |
356 | | return rv; |
357 | | } |
358 | | |
359 | | bool exists; |
360 | | rv = localDir->Exists(&exists); |
361 | | if (NS_SUCCEEDED(rv) && !exists) { |
362 | | rv = localDir->Create(nsIFile::DIRECTORY_TYPE, 0775); |
363 | | } |
364 | | if (NS_FAILED(rv)) { |
365 | | return rv; |
366 | | } |
367 | | #endif |
368 | | |
369 | 0 | localDir.forget(aLocalFile); |
370 | 0 |
|
371 | 0 | return rv; |
372 | 0 | } |
373 | | |
374 | | //***************************************************************************** |
375 | | // nsAppFileLocationProvider::nsIDirectoryServiceProvider2 |
376 | | //***************************************************************************** |
377 | | |
378 | | class nsAppDirectoryEnumerator : public nsSimpleEnumerator |
379 | | { |
380 | | public: |
381 | | |
382 | | /** |
383 | | * aKeyList is a null-terminated list of properties which are provided by aProvider |
384 | | * They do not need to be publicly defined keys. |
385 | | */ |
386 | | nsAppDirectoryEnumerator(nsIDirectoryServiceProvider* aProvider, |
387 | | const char* aKeyList[]) : |
388 | | mProvider(aProvider), |
389 | | mCurrentKey(aKeyList) |
390 | 0 | { |
391 | 0 | } |
392 | | |
393 | 0 | const nsID& DefaultInterface() override { return NS_GET_IID(nsIFile); } |
394 | | |
395 | | NS_IMETHOD HasMoreElements(bool* aResult) override |
396 | 0 | { |
397 | 0 | while (!mNext && *mCurrentKey) { |
398 | 0 | bool dontCare; |
399 | 0 | nsCOMPtr<nsIFile> testFile; |
400 | 0 | (void)mProvider->GetFile(*mCurrentKey++, &dontCare, getter_AddRefs(testFile)); |
401 | 0 | // Don't return a file which does not exist. |
402 | 0 | bool exists; |
403 | 0 | if (testFile && NS_SUCCEEDED(testFile->Exists(&exists)) && exists) { |
404 | 0 | mNext = testFile; |
405 | 0 | } |
406 | 0 | } |
407 | 0 | *aResult = mNext != nullptr; |
408 | 0 | return NS_OK; |
409 | 0 | } |
410 | | |
411 | | NS_IMETHOD GetNext(nsISupports** aResult) override |
412 | 0 | { |
413 | 0 | if (NS_WARN_IF(!aResult)) { |
414 | 0 | return NS_ERROR_INVALID_ARG; |
415 | 0 | } |
416 | 0 | *aResult = nullptr; |
417 | 0 |
|
418 | 0 | bool hasMore; |
419 | 0 | HasMoreElements(&hasMore); |
420 | 0 | if (!hasMore) { |
421 | 0 | return NS_ERROR_FAILURE; |
422 | 0 | } |
423 | 0 | |
424 | 0 | *aResult = mNext; |
425 | 0 | NS_IF_ADDREF(*aResult); |
426 | 0 | mNext = nullptr; |
427 | 0 |
|
428 | 0 | return *aResult ? NS_OK : NS_ERROR_FAILURE; |
429 | 0 | } |
430 | | |
431 | | protected: |
432 | | nsCOMPtr<nsIDirectoryServiceProvider> mProvider; |
433 | | const char** mCurrentKey; |
434 | | nsCOMPtr<nsIFile> mNext; |
435 | | }; |
436 | | |
437 | | /* nsPathsDirectoryEnumerator and PATH_SEPARATOR |
438 | | * are not used on MacOS/X. */ |
439 | | |
440 | | #if defined(XP_WIN) /* Win32 */ |
441 | | #define PATH_SEPARATOR ';' |
442 | | #else |
443 | 0 | #define PATH_SEPARATOR ':' |
444 | | #endif |
445 | | |
446 | | class nsPathsDirectoryEnumerator final |
447 | | : public nsAppDirectoryEnumerator |
448 | | { |
449 | 0 | ~nsPathsDirectoryEnumerator() {} |
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 | 0 | { |
463 | 0 | } |
464 | | |
465 | | NS_IMETHOD HasMoreElements(bool* aResult) override |
466 | 0 | { |
467 | 0 | if (mEndPath) |
468 | 0 | while (!mNext && *mEndPath) { |
469 | 0 | const char* pathVar = mEndPath; |
470 | 0 |
|
471 | 0 | // skip PATH_SEPARATORs at the begining of the mEndPath |
472 | 0 | while (*pathVar == PATH_SEPARATOR) { |
473 | 0 | ++pathVar; |
474 | 0 | } |
475 | 0 |
|
476 | 0 | do { |
477 | 0 | ++mEndPath; |
478 | 0 | } while (*mEndPath && *mEndPath != PATH_SEPARATOR); |
479 | 0 |
|
480 | 0 | nsCOMPtr<nsIFile> localFile; |
481 | 0 | NS_NewNativeLocalFile(Substring(pathVar, mEndPath), |
482 | 0 | true, |
483 | 0 | getter_AddRefs(localFile)); |
484 | 0 | if (*mEndPath == PATH_SEPARATOR) { |
485 | 0 | ++mEndPath; |
486 | 0 | } |
487 | 0 | // Don't return a "file" (directory) which does not exist. |
488 | 0 | bool exists; |
489 | 0 | if (localFile && |
490 | 0 | NS_SUCCEEDED(localFile->Exists(&exists)) && |
491 | 0 | exists) { |
492 | 0 | mNext = localFile; |
493 | 0 | } |
494 | 0 | } |
495 | 0 | if (mNext) { |
496 | 0 | *aResult = true; |
497 | 0 | } else { |
498 | 0 | nsAppDirectoryEnumerator::HasMoreElements(aResult); |
499 | 0 | } |
500 | 0 |
|
501 | 0 | return NS_OK; |
502 | 0 | } |
503 | | |
504 | | protected: |
505 | | const char* mEndPath; |
506 | | }; |
507 | | |
508 | | NS_IMETHODIMP |
509 | | nsAppFileLocationProvider::GetFiles(const char* aProp, |
510 | | nsISimpleEnumerator** aResult) |
511 | 3 | { |
512 | 3 | if (NS_WARN_IF(!aResult)) { |
513 | 0 | return NS_ERROR_INVALID_ARG; |
514 | 0 | } |
515 | 3 | *aResult = nullptr; |
516 | 3 | nsresult rv = NS_ERROR_FAILURE; |
517 | 3 | |
518 | 3 | if (!nsCRT::strcmp(aProp, NS_APP_PLUGINS_DIR_LIST)) { |
519 | | #ifdef MOZ_WIDGET_COCOA |
520 | | static const char* keys[] = { |
521 | | NS_APP_PLUGINS_DIR, |
522 | | NS_MACOSX_USER_PLUGIN_DIR, |
523 | | NS_MACOSX_LOCAL_PLUGIN_DIR, |
524 | | nullptr |
525 | | }; |
526 | | *aResult = new nsAppDirectoryEnumerator(this, keys); |
527 | | #else |
528 | | #ifdef XP_UNIX |
529 | 0 | static const char* keys[] = { nullptr, NS_USER_PLUGINS_DIR, NS_APP_PLUGINS_DIR, NS_SYSTEM_PLUGINS_DIR, nullptr }; |
530 | | #else |
531 | | static const char* keys[] = { nullptr, NS_USER_PLUGINS_DIR, NS_APP_PLUGINS_DIR, nullptr }; |
532 | | #endif |
533 | 0 | if (!keys[0] && !(keys[0] = PR_GetEnv("MOZ_PLUGIN_PATH"))) { |
534 | 0 | static const char nullstr = 0; |
535 | 0 | keys[0] = &nullstr; |
536 | 0 | } |
537 | 0 | *aResult = new nsPathsDirectoryEnumerator(this, keys); |
538 | 0 | #endif |
539 | 0 | NS_ADDREF(*aResult); |
540 | 0 | rv = NS_OK; |
541 | 0 | } |
542 | 3 | if (!strcmp(aProp, NS_APP_DISTRIBUTION_SEARCH_DIR_LIST)) { |
543 | 0 | return NS_NewEmptyEnumerator(aResult); |
544 | 0 | } |
545 | 3 | return rv; |
546 | 3 | } |