VirtualBox

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

最後變更 在這個檔案是 102457,由 vboxsync 提交於 12 月 前

libs/xpcom: Get rid of PL_strcmp/PL_strncmp and replace with IPRT equivalents, bugref:10545

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 16.6 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#include <iprt/string.h>
40
41#include "nsAppFileLocationProvider.h"
42#include "nsAppDirectoryServiceDefs.h"
43#include "nsDirectoryServiceDefs.h"
44#include "nsIAtom.h"
45#include "nsILocalFile.h"
46#include "nsString.h"
47#include "nsXPIDLString.h"
48#include "nsISimpleEnumerator.h"
49#include "nsCRT.h"
50
51#if defined(XP_UNIX)
52#include <unistd.h>
53#include <stdlib.h>
54#include <sys/param.h>
55#else
56# error "Not implemented"
57#endif
58
59#include <iprt/env.h>
60
61// WARNING: These hard coded names need to go away. They need to
62// come from localizable resources
63
64#if defined(XP_MAC) || defined(XP_MACOSX)
65#define APP_REGISTRY_NAME NS_LITERAL_CSTRING("Application Registry")
66#define ESSENTIAL_FILES NS_LITERAL_CSTRING("Essential Files")
67#elif defined(XP_WIN) || defined(XP_OS2)
68#define APP_REGISTRY_NAME NS_LITERAL_CSTRING("registry.dat")
69#else
70#define APP_REGISTRY_NAME NS_LITERAL_CSTRING("appreg")
71#endif
72
73// define default product directory
74#ifdef XP_MAC
75#define DEFAULT_PRODUCT_DIR NS_LITERAL_CSTRING("Mozilla")
76#else
77#define DEFAULT_PRODUCT_DIR NS_LITERAL_CSTRING(MOZ_USER_DIR)
78#endif
79
80// Locally defined keys used by nsAppDirectoryEnumerator
81#define NS_ENV_PLUGINS_DIR "EnvPlugins" // env var MOZ_PLUGIN_PATH
82#define NS_USER_PLUGINS_DIR "UserPlugins"
83
84#if defined(XP_MAC) || defined(XP_MACOSX)
85#define NS_MACOSX_USER_PLUGIN_DIR "OSXUserPlugins"
86#define NS_MACOSX_LOCAL_PLUGIN_DIR "OSXLocalPlugins"
87#define NS_MAC_CLASSIC_PLUGIN_DIR "MacSysPlugins"
88#endif
89
90#if defined(XP_MAC)
91#define DEFAULTS_DIR_NAME NS_LITERAL_CSTRING("Defaults")
92#define DEFAULTS_PREF_DIR_NAME NS_LITERAL_CSTRING("Pref")
93#define DEFAULTS_PROFILE_DIR_NAME NS_LITERAL_CSTRING("Profile")
94#define RES_DIR_NAME NS_LITERAL_CSTRING("Res")
95#define CHROME_DIR_NAME NS_LITERAL_CSTRING("Chrome")
96#define PLUGINS_DIR_NAME NS_LITERAL_CSTRING("Plug-ins")
97#define SEARCH_DIR_NAME NS_LITERAL_CSTRING("Search Plugins")
98#else
99#define DEFAULTS_DIR_NAME NS_LITERAL_CSTRING("defaults")
100#define DEFAULTS_PREF_DIR_NAME NS_LITERAL_CSTRING("pref")
101#define DEFAULTS_PROFILE_DIR_NAME NS_LITERAL_CSTRING("profile")
102#define RES_DIR_NAME NS_LITERAL_CSTRING("res")
103#define CHROME_DIR_NAME NS_LITERAL_CSTRING("chrome")
104#define PLUGINS_DIR_NAME NS_LITERAL_CSTRING("plugins")
105#define SEARCH_DIR_NAME NS_LITERAL_CSTRING("searchplugins")
106#endif
107
108//*****************************************************************************
109// nsAppFileLocationProvider::Constructor/Destructor
110//*****************************************************************************
111
112nsAppFileLocationProvider::nsAppFileLocationProvider()
113{
114}
115
116//*****************************************************************************
117// nsAppFileLocationProvider::nsISupports
118//*****************************************************************************
119
120NS_IMPL_THREADSAFE_ISUPPORTS2(nsAppFileLocationProvider, nsIDirectoryServiceProvider, nsIDirectoryServiceProvider2)
121
122//*****************************************************************************
123// nsAppFileLocationProvider::nsIDirectoryServiceProvider
124//*****************************************************************************
125
126NS_IMETHODIMP
127nsAppFileLocationProvider::GetFile(const char *prop, PRBool *persistant, nsIFile **_retval)
128{
129 nsCOMPtr<nsILocalFile> localFile;
130 nsresult rv = NS_ERROR_FAILURE;
131
132 NS_ENSURE_ARG(prop);
133 *_retval = nsnull;
134 *persistant = PR_TRUE;
135
136 if (RTStrCmp(prop, NS_APP_APPLICATION_REGISTRY_DIR) == 0)
137 {
138 rv = GetProductDirectory(getter_AddRefs(localFile));
139 }
140 else if (RTStrCmp(prop, NS_APP_APPLICATION_REGISTRY_FILE) == 0)
141 {
142 rv = GetProductDirectory(getter_AddRefs(localFile));
143 if (NS_SUCCEEDED(rv))
144 rv = localFile->AppendNative(APP_REGISTRY_NAME);
145 }
146 else if (RTStrCmp(prop, NS_APP_DEFAULTS_50_DIR) == 0)
147 {
148 rv = CloneMozBinDirectory(getter_AddRefs(localFile));
149 if (NS_SUCCEEDED(rv))
150 rv = localFile->AppendRelativeNativePath(DEFAULTS_DIR_NAME);
151 }
152 else if (RTStrCmp(prop, NS_APP_PREF_DEFAULTS_50_DIR) == 0)
153 {
154 rv = CloneMozBinDirectory(getter_AddRefs(localFile));
155 if (NS_SUCCEEDED(rv)) {
156 rv = localFile->AppendRelativeNativePath(DEFAULTS_DIR_NAME);
157 if (NS_SUCCEEDED(rv))
158 rv = localFile->AppendRelativeNativePath(DEFAULTS_PREF_DIR_NAME);
159 }
160 }
161 else if (RTStrCmp(prop, NS_APP_PROFILE_DEFAULTS_50_DIR) == 0 ||
162 RTStrCmp(prop, NS_APP_PROFILE_DEFAULTS_NLOC_50_DIR) == 0)
163 {
164 rv = CloneMozBinDirectory(getter_AddRefs(localFile));
165 if (NS_SUCCEEDED(rv)) {
166 rv = localFile->AppendRelativeNativePath(DEFAULTS_DIR_NAME);
167 if (NS_SUCCEEDED(rv))
168 rv = localFile->AppendRelativeNativePath(DEFAULTS_PROFILE_DIR_NAME);
169 }
170 }
171 else if (RTStrCmp(prop, NS_APP_USER_PROFILES_ROOT_DIR) == 0)
172 {
173 rv = GetDefaultUserProfileRoot(getter_AddRefs(localFile));
174 }
175 else if (RTStrCmp(prop, NS_APP_RES_DIR) == 0)
176 {
177 rv = CloneMozBinDirectory(getter_AddRefs(localFile));
178 if (NS_SUCCEEDED(rv))
179 rv = localFile->AppendRelativeNativePath(RES_DIR_NAME);
180 }
181 else if (RTStrCmp(prop, NS_APP_CHROME_DIR) == 0)
182 {
183 rv = CloneMozBinDirectory(getter_AddRefs(localFile));
184 if (NS_SUCCEEDED(rv))
185 rv = localFile->AppendRelativeNativePath(CHROME_DIR_NAME);
186 }
187 else if (RTStrCmp(prop, NS_APP_PLUGINS_DIR) == 0)
188 {
189 rv = CloneMozBinDirectory(getter_AddRefs(localFile));
190 if (NS_SUCCEEDED(rv))
191 rv = localFile->AppendRelativeNativePath(PLUGINS_DIR_NAME);
192 }
193 else if (RTStrCmp(prop, NS_ENV_PLUGINS_DIR) == 0)
194 {
195 NS_ERROR("Don't use nsAppFileLocationProvider::GetFile(NS_ENV_PLUGINS_DIR, ...). "
196 "Use nsAppFileLocationProvider::GetFiles(...).");
197 const char *pathVar = RTEnvGet("VBOX_XPCOM_PLUGIN_PATH");
198 if (pathVar)
199 rv = NS_NewNativeLocalFile(nsDependentCString(pathVar), PR_TRUE, getter_AddRefs(localFile));
200 }
201 else if (RTStrCmp(prop, NS_USER_PLUGINS_DIR) == 0)
202 {
203 rv = GetProductDirectory(getter_AddRefs(localFile));
204 if (NS_SUCCEEDED(rv))
205 rv = localFile->AppendRelativeNativePath(PLUGINS_DIR_NAME);
206 }
207 else if (RTStrCmp(prop, NS_APP_SEARCH_DIR) == 0)
208 {
209 rv = CloneMozBinDirectory(getter_AddRefs(localFile));
210 if (NS_SUCCEEDED(rv))
211 rv = localFile->AppendRelativeNativePath(SEARCH_DIR_NAME);
212 }
213 else if (RTStrCmp(prop, NS_APP_INSTALL_CLEANUP_DIR) == 0)
214 {
215 // This is cloned so that embeddors will have a hook to override
216 // with their own cleanup dir. See bugzilla bug #105087
217 rv = CloneMozBinDirectory(getter_AddRefs(localFile));
218 }
219
220 if (localFile && NS_SUCCEEDED(rv))
221 return localFile->QueryInterface(NS_GET_IID(nsIFile), (void**)_retval);
222
223 return rv;
224}
225
226
227NS_METHOD nsAppFileLocationProvider::CloneMozBinDirectory(nsILocalFile **aLocalFile)
228{
229 NS_ENSURE_ARG_POINTER(aLocalFile);
230 nsresult rv;
231
232 if (!mMozBinDirectory)
233 {
234 // Get the mozilla bin directory
235 // 1. Check the directory service first for NS_XPCOM_CURRENT_PROCESS_DIR
236 // This will be set if a directory was passed to NS_InitXPCOM
237 // 2. If that doesn't work, set it to be the current process directory
238 nsCOMPtr<nsIProperties>
239 directoryService(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv));
240 if (NS_FAILED(rv))
241 return rv;
242
243 rv = directoryService->Get(NS_XPCOM_CURRENT_PROCESS_DIR, NS_GET_IID(nsIFile), getter_AddRefs(mMozBinDirectory));
244 if (NS_FAILED(rv)) {
245 rv = directoryService->Get(NS_OS_CURRENT_PROCESS_DIR, NS_GET_IID(nsIFile), getter_AddRefs(mMozBinDirectory));
246 if (NS_FAILED(rv))
247 return rv;
248 }
249 }
250
251 nsCOMPtr<nsIFile> aFile;
252 rv = mMozBinDirectory->Clone(getter_AddRefs(aFile));
253 if (NS_FAILED(rv))
254 return rv;
255
256 nsCOMPtr<nsILocalFile> lfile = do_QueryInterface (aFile);
257 if (!lfile)
258 return NS_ERROR_FAILURE;
259
260 NS_IF_ADDREF(*aLocalFile = lfile);
261 return NS_OK;
262}
263
264
265//----------------------------------------------------------------------------------------
266// GetProductDirectory - Gets the directory which contains the application data folder
267//
268// UNIX : ~/.mozilla/
269// WIN : <Application Data folder on user's machine>\Mozilla
270// Mac : :Documents:Mozilla:
271//----------------------------------------------------------------------------------------
272NS_METHOD nsAppFileLocationProvider::GetProductDirectory(nsILocalFile **aLocalFile)
273{
274 NS_ENSURE_ARG_POINTER(aLocalFile);
275
276 nsresult rv;
277 PRBool exists;
278 nsCOMPtr<nsILocalFile> localDir;
279
280#if defined(XP_UNIX)
281 rv = NS_NewNativeLocalFile(nsDependentCString(RTEnvGet("HOME")), PR_TRUE, getter_AddRefs(localDir));
282 if (NS_FAILED(rv)) return rv;
283#else
284#error dont_know_how_to_get_product_dir_on_your_platform
285#endif
286
287 rv = localDir->AppendRelativeNativePath(DEFAULT_PRODUCT_DIR);
288 if (NS_FAILED(rv)) return rv;
289 rv = localDir->Exists(&exists);
290 if (NS_SUCCEEDED(rv) && !exists)
291 rv = localDir->Create(nsIFile::DIRECTORY_TYPE, 0700);
292 if (NS_FAILED(rv)) return rv;
293
294 *aLocalFile = localDir;
295 NS_ADDREF(*aLocalFile);
296
297 return rv;
298}
299
300
301//----------------------------------------------------------------------------------------
302// GetDefaultUserProfileRoot - Gets the directory which contains each user profile dir
303//
304// UNIX : ~/.mozilla/
305// WIN : <Application Data folder on user's machine>\Mozilla\Profiles
306// Mac : :Documents:Mozilla:Profiles:
307//----------------------------------------------------------------------------------------
308NS_METHOD nsAppFileLocationProvider::GetDefaultUserProfileRoot(nsILocalFile **aLocalFile)
309{
310 NS_ENSURE_ARG_POINTER(aLocalFile);
311
312 nsresult rv;
313 nsCOMPtr<nsILocalFile> localDir;
314
315 rv = GetProductDirectory(getter_AddRefs(localDir));
316 if (NS_FAILED(rv)) return rv;
317
318#if defined(XP_MAC) || defined(XP_MACOSX) || defined(XP_OS2) || defined(XP_WIN)
319 // These 3 platforms share this part of the path - do them as one
320 rv = localDir->AppendRelativeNativePath(NS_LITERAL_CSTRING("Profiles"));
321 if (NS_FAILED(rv)) return rv;
322
323 PRBool exists;
324 rv = localDir->Exists(&exists);
325 if (NS_SUCCEEDED(rv) && !exists)
326 rv = localDir->Create(nsIFile::DIRECTORY_TYPE, 0775);
327 if (NS_FAILED(rv)) return rv;
328#endif
329
330 *aLocalFile = localDir;
331 NS_ADDREF(*aLocalFile);
332
333 return rv;
334}
335
336//*****************************************************************************
337// nsAppFileLocationProvider::nsIDirectoryServiceProvider2
338//*****************************************************************************
339
340class nsAppDirectoryEnumerator : public nsISimpleEnumerator
341{
342 public:
343 NS_DECL_ISUPPORTS
344
345 /**
346 * aKeyList is a null-terminated list of properties which are provided by aProvider
347 * They do not need to be publicly defined keys.
348 */
349 nsAppDirectoryEnumerator(nsIDirectoryServiceProvider *aProvider,
350 const char* aKeyList[]) :
351 mProvider(aProvider),
352 mCurrentKey(aKeyList)
353 {
354 }
355
356 NS_IMETHOD HasMoreElements(PRBool *result)
357 {
358 while (!mNext && *mCurrentKey)
359 {
360 PRBool dontCare;
361 nsCOMPtr<nsIFile> testFile;
362 (void)mProvider->GetFile(*mCurrentKey++, &dontCare, getter_AddRefs(testFile));
363 // Don't return a file which does not exist.
364 PRBool exists;
365 if (testFile && NS_SUCCEEDED(testFile->Exists(&exists)) && exists)
366 mNext = testFile;
367 }
368 *result = mNext != nsnull;
369 return NS_OK;
370 }
371
372 NS_IMETHOD GetNext(nsISupports **result)
373 {
374 NS_ENSURE_ARG_POINTER(result);
375 *result = nsnull;
376
377 PRBool hasMore;
378 HasMoreElements(&hasMore);
379 if (!hasMore)
380 return NS_ERROR_FAILURE;
381
382 *result = mNext;
383 NS_IF_ADDREF(*result);
384 mNext = nsnull;
385
386 return *result ? NS_OK : NS_ERROR_FAILURE;
387 }
388
389 // Virtual destructor since subclass nsPathsDirectoryEnumerator
390 // does not re-implement Release()
391
392 virtual ~nsAppDirectoryEnumerator()
393 {
394 }
395
396 protected:
397 nsIDirectoryServiceProvider *mProvider;
398 const char** mCurrentKey;
399 nsCOMPtr<nsIFile> mNext;
400};
401
402NS_IMPL_ISUPPORTS1(nsAppDirectoryEnumerator, nsISimpleEnumerator)
403
404/* nsPathsDirectoryEnumerator and PATH_SEPARATOR
405 * are not used on MacOS/X. */
406
407#if defined(XP_WIN) || defined(XP_OS2)/* Win32, Win16, and OS/2 */
408#define PATH_SEPARATOR ';'
409#else /*if defined(XP_UNIX) || defined(XP_BEOS)*/
410#define PATH_SEPARATOR ':'
411#endif
412
413class nsPathsDirectoryEnumerator : public nsAppDirectoryEnumerator
414{
415 public:
416 /**
417 * aKeyList is a null-terminated list.
418 * The first element is a path list.
419 * The remainder are properties provided by aProvider.
420 * They do not need to be publicly defined keys.
421 */
422 nsPathsDirectoryEnumerator(nsIDirectoryServiceProvider *aProvider,
423 const char* aKeyList[]) :
424 nsAppDirectoryEnumerator(aProvider, aKeyList+1),
425 mEndPath(aKeyList[0])
426 {
427 }
428
429 NS_IMETHOD HasMoreElements(PRBool *result)
430 {
431 if (mEndPath)
432 while (!mNext && *mEndPath)
433 {
434 const char *pathVar = mEndPath;
435 do { ++mEndPath; } while (*mEndPath && *mEndPath != PATH_SEPARATOR);
436
437 nsCOMPtr<nsILocalFile> localFile;
438 NS_NewNativeLocalFile(Substring(pathVar, mEndPath),
439 PR_TRUE,
440 getter_AddRefs(localFile));
441 if (*mEndPath == PATH_SEPARATOR)
442 ++mEndPath;
443 // Don't return a "file" (directory) which does not exist.
444 PRBool exists;
445 if (localFile &&
446 NS_SUCCEEDED(localFile->Exists(&exists)) &&
447 exists)
448 mNext = localFile;
449 }
450 if (mNext)
451 *result = PR_TRUE;
452 else
453 nsAppDirectoryEnumerator::HasMoreElements(result);
454
455 return NS_OK;
456 }
457
458 protected:
459 const char *mEndPath;
460};
461
462NS_IMETHODIMP
463nsAppFileLocationProvider::GetFiles(const char *prop, nsISimpleEnumerator **_retval)
464{
465 NS_ENSURE_ARG_POINTER(_retval);
466 *_retval = nsnull;
467 nsresult rv = NS_ERROR_FAILURE;
468
469 if (!RTStrCmp(prop, NS_APP_PLUGINS_DIR_LIST))
470 {
471 static const char* keys[] = { nsnull, NS_APP_PLUGINS_DIR, nsnull };
472 if (!keys[0] && !(keys[0] = RTEnvGet("VBOX_XPCOM_PLUGIN_PATH"))) {
473 static const char nullstr = 0;
474 keys[0] = &nullstr;
475 }
476 *_retval = new nsPathsDirectoryEnumerator(this, keys);
477
478 NS_IF_ADDREF(*_retval);
479 rv = *_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
480 }
481 return rv;
482}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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