2014-05-05 21:30:43 +04:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
2012-05-21 15:12:37 +04:00
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
1999-12-22 04:56:45 +03:00
|
|
|
|
2013-12-09 06:52:54 +04:00
|
|
|
#include "mozilla/ArrayUtils.h"
|
2011-10-11 09:50:08 +04:00
|
|
|
|
2000-01-25 00:28:28 +03:00
|
|
|
#include "nsCOMPtr.h"
|
2005-06-07 23:35:20 +04:00
|
|
|
#include "nsAutoPtr.h"
|
2000-01-25 00:28:28 +03:00
|
|
|
#include "nsDirectoryService.h"
|
|
|
|
#include "nsLocalFile.h"
|
|
|
|
#include "nsDebug.h"
|
Bug 1411469 - Statically allocate static atoms. r=froydnj
Currently static atoms are stored on the heap, but their char buffers are
stored in read-only static memory.
This patch changes the representation of nsStaticAtom (thus making it a
non-trivial subclass of nsAtom). Instead of a pointer to the string, it now has
an mStringOffset field which is a 32-bit offset to the string. (This requires
placement of the string and the atom within the same object so that the offset
is known to be small. The docs and macros in nsStaticAtom.h handle that.)
Static and dynamic atoms now store their chars in different ways: nsStaticAtom
stores them inline, nsDynamicAtom has a pointer to separate storage. So
`mString` and GetStringBuffer() move from nsAtom to nsDynamicAtom.
The change to static atoms means they can be made constexpr and stored in
read-only memory instead of on the heap. On 64-bit this reduces the per-process
overhead by 16 bytes; on 32-bit the saving is 12 bytes. (Further reductions
will be possible in follow-up patches.)
The increased use of constexpr required multiple workarounds for MSVC.
- Multiple uses of MOZ_{PUSH,POP}_DISABLE_INTEGRAL_CONSTANT_OVERFLOW_WARNING to
disable warnings about (well-defined!) overflow of unsigned integer
arithmetic.
- The use of -Zc:externConstexpr on all files defining static atoms, to make
MSVC follow the C++ standard(!) and let constexpr variables have external
linkage.
- The use of -constexpr:steps300000 to increase the number of operations
allowed in a constexpr value, in order to handle gGkAtoms, which requires
hashing ~2,500 atom strings.
The patch also changes how HTML5 atoms are handled. They are now treated as
dynamic atoms, i.e. we have "dynamic normal" atoms and "dynamic HTML5 atoms",
and "dynamic atoms" covers both cases, and both are represented via
nsDynamicAtom. The main difference between the two kinds is that dynamic HTML5
atoms still aren't allowed to be used in various operations, most notably
AddRef()/Release(). All this also required moving nsDynamicAtom into the header
file.
There is a slight performance cost to all these changes: now that nsStaticAtom
and nsDynamicAtom store their chars in different ways, a conditional branch is
required in the following functions: Equals(), GetUTF16String(),
WeakAtom::as_slice().
Finally, in about:memory the "explicit/atoms/static/atom-objects" value is no
longer needed, because that memory is static instead of heap-allocated.
MozReview-Commit-ID: 4AxPv05ngZy
2018-03-08 04:59:11 +03:00
|
|
|
#include "nsGkAtoms.h"
|
2005-06-02 17:29:04 +04:00
|
|
|
#include "nsEnumeratorUtils.h"
|
1999-12-22 04:56:45 +03:00
|
|
|
|
2018-08-29 00:29:16 +03:00
|
|
|
#include "mozilla/SimpleEnumerator.h"
|
2005-06-07 23:35:20 +04:00
|
|
|
#include "nsICategoryManager.h"
|
|
|
|
#include "nsISimpleEnumerator.h"
|
|
|
|
|
2006-11-16 12:10:09 +03:00
|
|
|
#if defined(XP_WIN)
|
2000-01-25 00:28:28 +03:00
|
|
|
# include <windows.h>
|
|
|
|
# include <shlobj.h>
|
|
|
|
# include <stdlib.h>
|
|
|
|
# include <stdio.h>
|
2006-11-16 12:10:09 +03:00
|
|
|
#elif defined(XP_UNIX)
|
2000-01-25 00:28:28 +03:00
|
|
|
# include <unistd.h>
|
|
|
|
# include <stdlib.h>
|
|
|
|
# include <sys/param.h>
|
|
|
|
# include "prenv.h"
|
2010-04-27 16:57:34 +04:00
|
|
|
# ifdef MOZ_WIDGET_COCOA
|
2002-09-25 16:23:39 +04:00
|
|
|
# include <CoreServices/CoreServices.h>
|
2009-03-19 20:41:13 +03:00
|
|
|
# include <Carbon/Carbon.h>
|
2002-09-25 16:23:39 +04:00
|
|
|
# endif
|
2000-01-25 00:28:28 +03:00
|
|
|
#endif
|
|
|
|
|
2003-03-15 04:04:32 +03:00
|
|
|
#include "SpecialSystemDirectory.h"
|
2002-01-23 02:00:44 +03:00
|
|
|
#include "nsAppFileLocationProvider.h"
|
2017-09-28 04:49:48 +03:00
|
|
|
#include "BinaryPath.h"
|
2000-01-25 00:28:28 +03:00
|
|
|
|
2011-10-11 09:50:08 +04:00
|
|
|
using namespace mozilla;
|
|
|
|
|
2000-01-25 00:28:28 +03:00
|
|
|
//----------------------------------------------------------------------------------------
|
2012-06-06 06:08:30 +04:00
|
|
|
nsresult nsDirectoryService::GetCurrentProcessDirectory(nsIFile** aFile)
|
2000-01-25 00:28:28 +03:00
|
|
|
//----------------------------------------------------------------------------------------
|
|
|
|
{
|
2014-05-15 00:15:46 +04:00
|
|
|
if (NS_WARN_IF(!aFile)) {
|
2014-05-05 21:30:43 +04:00
|
|
|
return NS_ERROR_INVALID_ARG;
|
2014-05-15 00:15:46 +04:00
|
|
|
}
|
2014-05-05 21:30:43 +04:00
|
|
|
*aFile = nullptr;
|
|
|
|
|
|
|
|
// Set the component registry location:
|
2014-05-15 00:15:46 +04:00
|
|
|
if (!gService) {
|
2014-05-05 21:30:43 +04:00
|
|
|
return NS_ERROR_FAILURE;
|
2014-05-15 00:15:46 +04:00
|
|
|
}
|
2014-05-05 21:30:43 +04:00
|
|
|
|
2017-09-28 02:46:43 +03:00
|
|
|
nsCOMPtr<nsIFile> file;
|
|
|
|
gService->Get(NS_XPCOM_INIT_CURRENT_PROCESS_DIR, NS_GET_IID(nsIFile),
|
|
|
|
getter_AddRefs(file));
|
|
|
|
if (file) {
|
|
|
|
file.forget(aFile);
|
|
|
|
return NS_OK;
|
2014-05-05 21:30:43 +04:00
|
|
|
}
|
2000-01-25 23:43:47 +03:00
|
|
|
|
2017-09-28 04:49:48 +03:00
|
|
|
if (NS_SUCCEEDED(BinaryPath::GetFile(getter_AddRefs(file)))) {
|
|
|
|
return file->GetParent(aFile);
|
2014-05-05 21:30:43 +04:00
|
|
|
}
|
|
|
|
NS_ERROR("unable to get current process directory");
|
|
|
|
return NS_ERROR_FAILURE;
|
2000-01-25 00:28:28 +03:00
|
|
|
} // GetCurrentProcessDirectory()
|
|
|
|
|
2016-07-21 19:54:16 +03:00
|
|
|
StaticRefPtr<nsDirectoryService> nsDirectoryService::gService;
|
1999-12-22 04:56:45 +03:00
|
|
|
|
2013-07-24 11:40:40 +04:00
|
|
|
nsDirectoryService::nsDirectoryService() : mHashtable(128) {}
|
1999-12-22 04:56:45 +03:00
|
|
|
|
2014-05-15 00:15:46 +04:00
|
|
|
nsresult nsDirectoryService::Create(nsISupports* aOuter, REFNSIID aIID,
|
|
|
|
void** aResult) {
|
|
|
|
if (NS_WARN_IF(!aResult)) {
|
2014-05-05 21:30:43 +04:00
|
|
|
return NS_ERROR_INVALID_ARG;
|
2014-05-15 00:15:46 +04:00
|
|
|
}
|
|
|
|
if (NS_WARN_IF(aOuter)) {
|
2014-05-05 21:30:43 +04:00
|
|
|
return NS_ERROR_NO_AGGREGATION;
|
2014-05-15 00:15:46 +04:00
|
|
|
}
|
2005-06-07 23:35:20 +04:00
|
|
|
|
2014-05-15 00:15:46 +04:00
|
|
|
if (!gService) {
|
2014-05-05 21:30:43 +04:00
|
|
|
return NS_ERROR_NOT_INITIALIZED;
|
|
|
|
}
|
2005-06-07 23:35:20 +04:00
|
|
|
|
2014-05-05 21:30:43 +04:00
|
|
|
return gService->QueryInterface(aIID, aResult);
|
2000-04-25 05:48:02 +04:00
|
|
|
}
|
|
|
|
|
2005-06-07 23:35:20 +04:00
|
|
|
NS_IMETHODIMP
|
2003-04-04 00:02:03 +04:00
|
|
|
nsDirectoryService::Init() {
|
2018-06-18 08:43:11 +03:00
|
|
|
MOZ_ASSERT_UNREACHABLE("nsDirectoryService::Init() for internal use only!");
|
2014-05-05 21:30:43 +04:00
|
|
|
return NS_OK;
|
2005-06-07 23:35:20 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void nsDirectoryService::RealInit() {
|
2014-05-05 21:30:43 +04:00
|
|
|
NS_ASSERTION(!gService,
|
|
|
|
"nsDirectoryService::RealInit Mustn't initialize twice!");
|
|
|
|
|
2016-07-21 19:54:16 +03:00
|
|
|
gService = new nsDirectoryService();
|
2005-06-07 23:35:20 +04:00
|
|
|
|
2014-05-05 21:30:43 +04:00
|
|
|
// Let the list hold the only reference to the provider.
|
2014-05-15 00:15:46 +04:00
|
|
|
nsAppFileLocationProvider* defaultProvider = new nsAppFileLocationProvider;
|
2016-07-21 19:54:16 +03:00
|
|
|
gService->mProviders.AppendElement(defaultProvider);
|
1999-12-22 04:56:45 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
nsDirectoryService::~nsDirectoryService() {}
|
|
|
|
|
2014-05-15 00:15:46 +04:00
|
|
|
NS_IMPL_ISUPPORTS(nsDirectoryService, nsIProperties, nsIDirectoryService,
|
|
|
|
nsIDirectoryServiceProvider, nsIDirectoryServiceProvider2)
|
1999-12-22 04:56:45 +03:00
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2014-05-15 00:15:46 +04:00
|
|
|
nsDirectoryService::Undefine(const char* aProp) {
|
|
|
|
if (NS_WARN_IF(!aProp)) {
|
2014-05-05 21:30:43 +04:00
|
|
|
return NS_ERROR_INVALID_ARG;
|
2014-05-15 00:15:46 +04:00
|
|
|
}
|
2007-05-13 20:48:39 +04:00
|
|
|
|
2014-05-15 00:15:46 +04:00
|
|
|
nsDependentCString key(aProp);
|
2017-07-05 03:01:44 +03:00
|
|
|
return mHashtable.Remove(key) ? NS_OK : NS_ERROR_FAILURE;
|
2014-05-05 21:30:43 +04:00
|
|
|
}
|
2002-08-27 00:36:44 +04:00
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2014-05-15 00:15:46 +04:00
|
|
|
nsDirectoryService::GetKeys(uint32_t* aCount, char*** aKeys) {
|
2014-05-05 21:30:43 +04:00
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
1999-12-22 04:56:45 +03:00
|
|
|
}
|
|
|
|
|
2015-01-18 05:05:15 +03:00
|
|
|
struct MOZ_STACK_CLASS FileData {
|
2014-05-15 00:15:46 +04:00
|
|
|
FileData(const char* aProperty, const nsIID& aUUID)
|
|
|
|
: property(aProperty), data(nullptr), persistent(true), uuid(aUUID) {}
|
2014-05-05 21:30:43 +04:00
|
|
|
|
2001-11-02 18:29:57 +03:00
|
|
|
const char* property;
|
2015-01-18 05:05:15 +03:00
|
|
|
nsCOMPtr<nsISupports> data;
|
2011-09-29 10:19:26 +04:00
|
|
|
bool persistent;
|
2001-11-02 18:29:57 +03:00
|
|
|
const nsIID& uuid;
|
|
|
|
};
|
2000-02-22 00:51:47 +03:00
|
|
|
|
2014-05-15 00:15:46 +04:00
|
|
|
static bool FindProviderFile(nsIDirectoryServiceProvider* aElement,
|
|
|
|
FileData* aData) {
|
2000-09-08 08:57:33 +04:00
|
|
|
nsresult rv;
|
2012-08-21 16:02:37 +04:00
|
|
|
if (aData->uuid.Equals(NS_GET_IID(nsISimpleEnumerator))) {
|
2014-05-05 21:30:43 +04:00
|
|
|
// Not all providers implement this iface
|
|
|
|
nsCOMPtr<nsIDirectoryServiceProvider2> prov2 = do_QueryInterface(aElement);
|
2014-05-15 00:15:46 +04:00
|
|
|
if (prov2) {
|
2014-05-05 21:30:43 +04:00
|
|
|
nsCOMPtr<nsISimpleEnumerator> newFiles;
|
|
|
|
rv = prov2->GetFiles(aData->property, getter_AddRefs(newFiles));
|
|
|
|
if (NS_SUCCEEDED(rv) && newFiles) {
|
|
|
|
if (aData->data) {
|
|
|
|
nsCOMPtr<nsISimpleEnumerator> unionFiles;
|
|
|
|
|
|
|
|
NS_NewUnionEnumerator(getter_AddRefs(unionFiles),
|
2015-01-18 05:05:15 +03:00
|
|
|
(nsISimpleEnumerator*)aData->data.get(),
|
|
|
|
newFiles);
|
2014-05-05 21:30:43 +04:00
|
|
|
|
2014-05-15 00:15:46 +04:00
|
|
|
if (unionFiles) {
|
|
|
|
unionFiles.swap(*(nsISimpleEnumerator**)&aData->data);
|
|
|
|
}
|
|
|
|
} else {
|
2015-01-18 05:05:15 +03:00
|
|
|
aData->data = newFiles;
|
2014-05-05 21:30:43 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
aData->persistent = false; // Enumerators can never be persistent
|
|
|
|
return rv == NS_SUCCESS_AGGREGATE_RESULT;
|
2001-11-02 18:29:57 +03:00
|
|
|
}
|
2014-05-05 21:30:43 +04:00
|
|
|
}
|
2014-05-15 00:15:46 +04:00
|
|
|
} else {
|
2014-05-05 21:30:43 +04:00
|
|
|
rv = aElement->GetFile(aData->property, &aData->persistent,
|
2014-05-15 00:15:46 +04:00
|
|
|
(nsIFile**)&aData->data);
|
|
|
|
if (NS_SUCCEEDED(rv) && aData->data) {
|
2014-05-05 21:30:43 +04:00
|
|
|
return false;
|
2014-05-15 00:15:46 +04:00
|
|
|
}
|
2001-11-02 18:29:57 +03:00
|
|
|
}
|
2000-02-22 00:51:47 +03:00
|
|
|
|
2011-10-17 18:59:28 +04:00
|
|
|
return true;
|
2000-02-22 00:51:47 +03:00
|
|
|
}
|
|
|
|
|
1999-12-22 04:56:45 +03:00
|
|
|
NS_IMETHODIMP
|
2014-05-15 00:15:46 +04:00
|
|
|
nsDirectoryService::Get(const char* aProp, const nsIID& aUuid, void** aResult) {
|
|
|
|
if (NS_WARN_IF(!aProp)) {
|
2014-05-05 21:30:43 +04:00
|
|
|
return NS_ERROR_INVALID_ARG;
|
2014-05-15 00:15:46 +04:00
|
|
|
}
|
2007-05-13 20:48:39 +04:00
|
|
|
|
2014-05-15 00:15:46 +04:00
|
|
|
nsDependentCString key(aProp);
|
2013-07-24 11:40:40 +04:00
|
|
|
|
2014-05-05 21:30:43 +04:00
|
|
|
nsCOMPtr<nsIFile> cachedFile = mHashtable.Get(key);
|
2000-06-21 10:32:45 +04:00
|
|
|
|
2014-05-05 21:30:43 +04:00
|
|
|
if (cachedFile) {
|
|
|
|
nsCOMPtr<nsIFile> cloneFile;
|
|
|
|
cachedFile->Clone(getter_AddRefs(cloneFile));
|
2014-05-15 00:15:46 +04:00
|
|
|
return cloneFile->QueryInterface(aUuid, aResult);
|
2014-05-05 21:30:43 +04:00
|
|
|
}
|
2001-07-31 23:05:34 +04:00
|
|
|
|
2014-05-05 21:30:43 +04:00
|
|
|
// it is not one of our defaults, lets check any providers
|
2014-05-15 00:15:46 +04:00
|
|
|
FileData fileData(aProp, aUuid);
|
2001-07-31 23:05:34 +04:00
|
|
|
|
2014-05-05 21:30:43 +04:00
|
|
|
for (int32_t i = mProviders.Length() - 1; i >= 0; i--) {
|
|
|
|
if (!FindProviderFile(mProviders[i], &fileData)) {
|
|
|
|
break;
|
2012-08-21 16:02:37 +04:00
|
|
|
}
|
2014-05-05 21:30:43 +04:00
|
|
|
}
|
2014-05-15 00:15:46 +04:00
|
|
|
if (fileData.data) {
|
|
|
|
if (fileData.persistent) {
|
2015-01-18 05:05:15 +03:00
|
|
|
Set(aProp, static_cast<nsIFile*>(fileData.data.get()));
|
2001-07-31 23:05:34 +04:00
|
|
|
}
|
2014-05-15 00:15:46 +04:00
|
|
|
nsresult rv = (fileData.data)->QueryInterface(aUuid, aResult);
|
2015-01-18 05:05:15 +03:00
|
|
|
fileData.data = nullptr; // AddRef occurs in FindProviderFile()
|
2014-05-05 21:30:43 +04:00
|
|
|
return rv;
|
|
|
|
}
|
2002-04-27 09:33:09 +04:00
|
|
|
|
2014-05-05 21:30:43 +04:00
|
|
|
FindProviderFile(static_cast<nsIDirectoryServiceProvider*>(this), &fileData);
|
2014-05-15 00:15:46 +04:00
|
|
|
if (fileData.data) {
|
|
|
|
if (fileData.persistent) {
|
2015-01-18 05:05:15 +03:00
|
|
|
Set(aProp, static_cast<nsIFile*>(fileData.data.get()));
|
1999-12-22 04:56:45 +03:00
|
|
|
}
|
2014-05-15 00:15:46 +04:00
|
|
|
nsresult rv = (fileData.data)->QueryInterface(aUuid, aResult);
|
2015-01-18 05:05:15 +03:00
|
|
|
fileData.data = nullptr; // AddRef occurs in FindProviderFile()
|
2014-05-05 21:30:43 +04:00
|
|
|
return rv;
|
|
|
|
}
|
1999-12-22 04:56:45 +03:00
|
|
|
|
2014-05-05 21:30:43 +04:00
|
|
|
return NS_ERROR_FAILURE;
|
1999-12-22 04:56:45 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2014-05-15 00:15:46 +04:00
|
|
|
nsDirectoryService::Set(const char* aProp, nsISupports* aValue) {
|
|
|
|
if (NS_WARN_IF(!aProp)) {
|
2014-05-05 21:30:43 +04:00
|
|
|
return NS_ERROR_INVALID_ARG;
|
2014-05-15 00:15:46 +04:00
|
|
|
}
|
2017-06-28 02:03:17 +03:00
|
|
|
if (!aValue) {
|
2014-05-05 21:30:43 +04:00
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
2002-04-27 09:33:09 +04:00
|
|
|
|
2017-06-28 02:03:17 +03:00
|
|
|
nsDependentCString key(aProp);
|
|
|
|
if (auto entry = mHashtable.LookupForAdd(key)) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
} else {
|
|
|
|
nsCOMPtr<nsIFile> ourFile = do_QueryInterface(aValue);
|
|
|
|
if (ourFile) {
|
|
|
|
nsCOMPtr<nsIFile> cloneFile;
|
|
|
|
ourFile->Clone(getter_AddRefs(cloneFile));
|
|
|
|
entry.OrInsert([&cloneFile]() { return cloneFile.forget(); });
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
mHashtable.Remove(key); // another hashtable lookup, but should be rare
|
2014-05-05 21:30:43 +04:00
|
|
|
}
|
|
|
|
return NS_ERROR_FAILURE;
|
1999-12-22 04:56:45 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2014-05-15 00:15:46 +04:00
|
|
|
nsDirectoryService::Has(const char* aProp, bool* aResult) {
|
|
|
|
if (NS_WARN_IF(!aProp)) {
|
2014-05-05 21:30:43 +04:00
|
|
|
return NS_ERROR_INVALID_ARG;
|
2014-05-15 00:15:46 +04:00
|
|
|
}
|
2014-05-05 21:30:43 +04:00
|
|
|
|
2014-05-15 00:15:46 +04:00
|
|
|
*aResult = false;
|
2014-05-05 21:30:43 +04:00
|
|
|
nsCOMPtr<nsIFile> value;
|
2014-05-15 00:15:46 +04:00
|
|
|
nsresult rv = Get(aProp, NS_GET_IID(nsIFile), getter_AddRefs(value));
|
|
|
|
if (NS_FAILED(rv)) {
|
2014-05-05 21:30:43 +04:00
|
|
|
return NS_OK;
|
2014-05-15 00:15:46 +04:00
|
|
|
}
|
2014-05-05 21:30:43 +04:00
|
|
|
|
2014-05-15 00:15:46 +04:00
|
|
|
if (value) {
|
|
|
|
*aResult = true;
|
2014-05-05 21:30:43 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
1999-12-22 04:56:45 +03:00
|
|
|
}
|
2000-02-22 00:51:47 +03:00
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2014-05-15 00:15:46 +04:00
|
|
|
nsDirectoryService::RegisterProvider(nsIDirectoryServiceProvider* aProv) {
|
|
|
|
if (!aProv) {
|
2014-05-05 21:30:43 +04:00
|
|
|
return NS_ERROR_FAILURE;
|
2014-05-15 00:15:46 +04:00
|
|
|
}
|
2000-04-25 05:48:02 +04:00
|
|
|
|
2014-05-15 00:15:46 +04:00
|
|
|
mProviders.AppendElement(aProv);
|
2014-05-05 21:30:43 +04:00
|
|
|
return NS_OK;
|
2000-02-22 00:51:47 +03:00
|
|
|
}
|
|
|
|
|
2005-06-07 23:35:20 +04:00
|
|
|
void nsDirectoryService::RegisterCategoryProviders() {
|
2014-05-05 21:30:43 +04:00
|
|
|
nsCOMPtr<nsICategoryManager> catman(
|
|
|
|
do_GetService(NS_CATEGORYMANAGER_CONTRACTID));
|
2014-05-15 00:15:46 +04:00
|
|
|
if (!catman) {
|
2014-05-05 21:30:43 +04:00
|
|
|
return;
|
2014-05-15 00:15:46 +04:00
|
|
|
}
|
2014-05-05 21:30:43 +04:00
|
|
|
|
|
|
|
nsCOMPtr<nsISimpleEnumerator> entries;
|
|
|
|
catman->EnumerateCategory(XPCOM_DIRECTORY_PROVIDER_CATEGORY,
|
|
|
|
getter_AddRefs(entries));
|
|
|
|
|
2018-08-29 00:29:16 +03:00
|
|
|
for (auto& categoryEntry : SimpleEnumerator<nsICategoryEntry>(entries)) {
|
|
|
|
nsAutoCString contractID;
|
|
|
|
categoryEntry->GetValue(contractID);
|
2014-05-05 21:30:43 +04:00
|
|
|
|
2018-08-29 00:29:16 +03:00
|
|
|
if (nsCOMPtr<nsIDirectoryServiceProvider> provider =
|
|
|
|
do_GetService(contractID.get())) {
|
|
|
|
RegisterProvider(provider);
|
2005-06-07 23:35:20 +04:00
|
|
|
}
|
2014-05-05 21:30:43 +04:00
|
|
|
}
|
2005-06-07 23:35:20 +04:00
|
|
|
}
|
|
|
|
|
2000-09-08 08:57:33 +04:00
|
|
|
NS_IMETHODIMP
|
2014-05-15 00:15:46 +04:00
|
|
|
nsDirectoryService::UnregisterProvider(nsIDirectoryServiceProvider* aProv) {
|
|
|
|
if (!aProv) {
|
2014-05-05 21:30:43 +04:00
|
|
|
return NS_ERROR_FAILURE;
|
2014-05-15 00:15:46 +04:00
|
|
|
}
|
2000-09-08 08:57:33 +04:00
|
|
|
|
2014-05-15 00:15:46 +04:00
|
|
|
mProviders.RemoveElement(aProv);
|
2014-05-05 21:30:43 +04:00
|
|
|
return NS_OK;
|
2000-09-08 08:57:33 +04:00
|
|
|
}
|
2000-02-22 00:51:47 +03:00
|
|
|
|
2014-09-10 15:36:17 +04:00
|
|
|
#if defined(MOZ_CONTENT_SANDBOX) && defined(XP_WIN)
|
2015-05-18 13:51:07 +03:00
|
|
|
static nsresult GetLowIntegrityTempBase(nsIFile** aLowIntegrityTempBase) {
|
2014-09-10 15:36:17 +04:00
|
|
|
nsCOMPtr<nsIFile> localFile;
|
|
|
|
nsresult rv =
|
|
|
|
GetSpecialSystemDirectory(Win_LocalAppdataLow, getter_AddRefs(localFile));
|
|
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2015-05-18 13:51:07 +03:00
|
|
|
rv = localFile->Append(NS_LITERAL_STRING(MOZ_USER_DIR));
|
2014-09-15 19:51:28 +04:00
|
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2015-05-18 13:51:07 +03:00
|
|
|
localFile.forget(aLowIntegrityTempBase);
|
2014-09-10 15:36:17 +04:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2000-04-25 05:48:02 +04:00
|
|
|
// DO NOT ADD ANY LOCATIONS TO THIS FUNCTION UNTIL YOU TALK TO:
|
|
|
|
// dougt@netscape.com. This is meant to be a place of xpcom or system specific
|
|
|
|
// file locations, not application specific locations. If you need the later,
|
|
|
|
// register a callback for your application.
|
2000-02-22 00:51:47 +03:00
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2014-05-15 00:15:46 +04:00
|
|
|
nsDirectoryService::GetFile(const char* aProp, bool* aPersistent,
|
|
|
|
nsIFile** aResult) {
|
2014-05-05 21:30:43 +04:00
|
|
|
nsCOMPtr<nsIFile> localFile;
|
|
|
|
nsresult rv = NS_ERROR_FAILURE;
|
2000-02-22 00:51:47 +03:00
|
|
|
|
2014-05-15 00:15:46 +04:00
|
|
|
*aResult = nullptr;
|
|
|
|
*aPersistent = true;
|
2000-02-22 00:51:47 +03:00
|
|
|
|
2017-10-03 01:05:19 +03:00
|
|
|
RefPtr<nsAtom> inAtom = NS_Atomize(aProp);
|
2014-05-05 21:30:43 +04:00
|
|
|
|
|
|
|
// check to see if it is one of our defaults
|
|
|
|
|
2018-08-15 08:46:00 +03:00
|
|
|
if (inAtom == nsGkAtoms::DirectoryService_CurrentProcess ||
|
|
|
|
inAtom == nsGkAtoms::DirectoryService_OS_CurrentProcessDirectory) {
|
2014-05-05 21:30:43 +04:00
|
|
|
rv = GetCurrentProcessDirectory(getter_AddRefs(localFile));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Unless otherwise set, the core pieces of the GRE exist
|
|
|
|
// in the current process directory.
|
2018-08-15 08:46:00 +03:00
|
|
|
else if (inAtom == nsGkAtoms::DirectoryService_GRE_Directory ||
|
|
|
|
inAtom == nsGkAtoms::DirectoryService_GRE_BinDirectory) {
|
2014-05-05 21:30:43 +04:00
|
|
|
rv = GetCurrentProcessDirectory(getter_AddRefs(localFile));
|
2018-08-15 08:46:00 +03:00
|
|
|
} else if (inAtom == nsGkAtoms::DirectoryService_OS_TemporaryDirectory) {
|
2014-05-05 21:30:43 +04:00
|
|
|
rv = GetSpecialSystemDirectory(OS_TemporaryDirectory,
|
|
|
|
getter_AddRefs(localFile));
|
2018-08-15 08:46:00 +03:00
|
|
|
} else if (inAtom == nsGkAtoms::DirectoryService_OS_CurrentProcessDirectory) {
|
2014-05-05 21:30:43 +04:00
|
|
|
rv = GetSpecialSystemDirectory(OS_CurrentProcessDirectory,
|
|
|
|
getter_AddRefs(localFile));
|
2018-08-15 08:46:00 +03:00
|
|
|
} else if (inAtom == nsGkAtoms::DirectoryService_OS_CurrentWorkingDirectory) {
|
2014-05-05 21:30:43 +04:00
|
|
|
rv = GetSpecialSystemDirectory(OS_CurrentWorkingDirectory,
|
|
|
|
getter_AddRefs(localFile));
|
|
|
|
}
|
2010-04-27 16:57:34 +04:00
|
|
|
#if defined(MOZ_WIDGET_COCOA)
|
2018-08-15 08:46:00 +03:00
|
|
|
else if (inAtom == nsGkAtoms::DirectoryService_SystemDirectory) {
|
2014-05-05 21:30:43 +04:00
|
|
|
rv = GetOSXFolderType(kClassicDomain, kSystemFolderType,
|
|
|
|
getter_AddRefs(localFile));
|
2018-08-15 08:46:00 +03:00
|
|
|
} else if (inAtom == nsGkAtoms::DirectoryService_UserLibDirectory) {
|
2014-05-05 21:30:43 +04:00
|
|
|
rv = GetOSXFolderType(kUserDomain, kDomainLibraryFolderType,
|
|
|
|
getter_AddRefs(localFile));
|
2018-03-22 11:07:40 +03:00
|
|
|
} else if (inAtom == nsGkAtoms::Home) {
|
2014-05-05 21:30:43 +04:00
|
|
|
rv = GetOSXFolderType(kUserDomain, kDomainTopLevelFolderType,
|
|
|
|
getter_AddRefs(localFile));
|
2018-08-15 08:46:00 +03:00
|
|
|
} else if (inAtom == nsGkAtoms::DirectoryService_DefaultDownloadDirectory) {
|
2014-05-05 21:30:43 +04:00
|
|
|
rv = GetOSXFolderType(kUserDomain, kDownloadsFolderType,
|
|
|
|
getter_AddRefs(localFile));
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
rv = GetOSXFolderType(kUserDomain, kDesktopFolderType,
|
|
|
|
getter_AddRefs(localFile));
|
2003-04-07 11:02:32 +04:00
|
|
|
}
|
2018-08-15 08:46:00 +03:00
|
|
|
} else if (inAtom == nsGkAtoms::DirectoryService_OS_DesktopDirectory) {
|
2014-05-05 21:30:43 +04:00
|
|
|
rv = GetOSXFolderType(kUserDomain, kDesktopFolderType,
|
|
|
|
getter_AddRefs(localFile));
|
2018-08-15 08:46:00 +03:00
|
|
|
} else if (inAtom == nsGkAtoms::DirectoryService_LocalApplicationsDirectory) {
|
2014-05-05 21:30:43 +04:00
|
|
|
rv = GetOSXFolderType(kLocalDomain, kApplicationsFolderType,
|
|
|
|
getter_AddRefs(localFile));
|
2018-08-15 08:46:00 +03:00
|
|
|
} else if (inAtom == nsGkAtoms::DirectoryService_UserPreferencesDirectory) {
|
2014-05-05 21:30:43 +04:00
|
|
|
rv = GetOSXFolderType(kUserDomain, kPreferencesFolderType,
|
|
|
|
getter_AddRefs(localFile));
|
2018-08-15 08:46:00 +03:00
|
|
|
} else if (inAtom == nsGkAtoms::DirectoryService_PictureDocumentsDirectory) {
|
2014-05-05 21:30:43 +04:00
|
|
|
rv = GetOSXFolderType(kUserDomain, kPictureDocumentsFolderType,
|
|
|
|
getter_AddRefs(localFile));
|
|
|
|
}
|
2000-11-29 02:27:38 +03:00
|
|
|
#elif defined(XP_WIN)
|
2018-08-15 08:46:00 +03:00
|
|
|
else if (inAtom == nsGkAtoms::DirectoryService_SystemDirectory) {
|
2014-05-05 21:30:43 +04:00
|
|
|
rv = GetSpecialSystemDirectory(Win_SystemDirectory,
|
|
|
|
getter_AddRefs(localFile));
|
2018-08-15 08:46:00 +03:00
|
|
|
} else if (inAtom == nsGkAtoms::DirectoryService_WindowsDirectory) {
|
2014-05-05 21:30:43 +04:00
|
|
|
rv = GetSpecialSystemDirectory(Win_WindowsDirectory,
|
|
|
|
getter_AddRefs(localFile));
|
2018-08-15 08:46:00 +03:00
|
|
|
} else if (inAtom == nsGkAtoms::DirectoryService_WindowsProgramFiles) {
|
2014-05-05 21:30:43 +04:00
|
|
|
rv = GetSpecialSystemDirectory(Win_ProgramFiles, getter_AddRefs(localFile));
|
2018-03-22 11:07:40 +03:00
|
|
|
} else if (inAtom == nsGkAtoms::Home) {
|
2014-05-05 21:30:43 +04:00
|
|
|
rv =
|
|
|
|
GetSpecialSystemDirectory(Win_HomeDirectory, getter_AddRefs(localFile));
|
2018-08-15 08:46:00 +03:00
|
|
|
} else if (inAtom == nsGkAtoms::DirectoryService_Programs) {
|
2014-05-05 21:30:43 +04:00
|
|
|
rv = GetSpecialSystemDirectory(Win_Programs, getter_AddRefs(localFile));
|
2018-08-15 08:46:00 +03:00
|
|
|
} else if (inAtom == nsGkAtoms::DirectoryService_Favorites) {
|
2014-05-05 21:30:43 +04:00
|
|
|
rv = GetSpecialSystemDirectory(Win_Favorites, getter_AddRefs(localFile));
|
2018-08-15 08:46:00 +03:00
|
|
|
} else if (inAtom == nsGkAtoms::DirectoryService_OS_DesktopDirectory) {
|
2014-05-05 21:30:43 +04:00
|
|
|
rv = GetSpecialSystemDirectory(Win_Desktopdirectory,
|
|
|
|
getter_AddRefs(localFile));
|
2018-08-15 08:46:00 +03:00
|
|
|
} else if (inAtom == nsGkAtoms::DirectoryService_Appdata) {
|
2014-05-05 21:30:43 +04:00
|
|
|
rv = GetSpecialSystemDirectory(Win_Appdata, getter_AddRefs(localFile));
|
2018-08-15 08:46:00 +03:00
|
|
|
} else if (inAtom == nsGkAtoms::DirectoryService_LocalAppdata) {
|
2014-05-05 21:30:43 +04:00
|
|
|
rv = GetSpecialSystemDirectory(Win_LocalAppdata, getter_AddRefs(localFile));
|
2014-09-10 15:36:17 +04:00
|
|
|
# if defined(MOZ_CONTENT_SANDBOX)
|
2018-08-15 08:46:00 +03:00
|
|
|
} else if (inAtom == nsGkAtoms::DirectoryService_LocalAppdataLow) {
|
2014-09-10 15:36:17 +04:00
|
|
|
rv = GetSpecialSystemDirectory(Win_LocalAppdataLow,
|
|
|
|
getter_AddRefs(localFile));
|
2018-08-15 08:46:00 +03:00
|
|
|
} else if (inAtom == nsGkAtoms::DirectoryService_LowIntegrityTempBase) {
|
2015-05-18 13:51:07 +03:00
|
|
|
rv = GetLowIntegrityTempBase(getter_AddRefs(localFile));
|
2014-09-10 15:36:17 +04:00
|
|
|
# endif
|
2018-08-15 08:46:00 +03:00
|
|
|
} else if (inAtom == nsGkAtoms::DirectoryService_WinCookiesDirectory) {
|
2014-05-05 21:30:43 +04:00
|
|
|
rv = GetSpecialSystemDirectory(Win_Cookies, getter_AddRefs(localFile));
|
2018-08-15 08:46:00 +03:00
|
|
|
} else if (inAtom == nsGkAtoms::DirectoryService_DefaultDownloadDirectory) {
|
2014-05-05 21:30:43 +04:00
|
|
|
rv = GetSpecialSystemDirectory(Win_Downloads, getter_AddRefs(localFile));
|
|
|
|
}
|
2002-09-25 16:23:39 +04:00
|
|
|
#elif defined(XP_UNIX)
|
2018-06-25 09:55:00 +03:00
|
|
|
else if (inAtom == nsGkAtoms::Home) {
|
2014-05-05 21:30:43 +04:00
|
|
|
rv = GetSpecialSystemDirectory(Unix_HomeDirectory,
|
|
|
|
getter_AddRefs(localFile));
|
2018-08-15 08:46:00 +03:00
|
|
|
} else if (inAtom == nsGkAtoms::DirectoryService_OS_DesktopDirectory) {
|
2014-05-05 21:30:43 +04:00
|
|
|
rv = GetSpecialSystemDirectory(Unix_XDG_Desktop, getter_AddRefs(localFile));
|
2014-05-15 00:15:46 +04:00
|
|
|
*aPersistent = false;
|
2018-08-15 08:46:00 +03:00
|
|
|
} else if (inAtom == nsGkAtoms::DirectoryService_DefaultDownloadDirectory) {
|
2014-05-05 21:30:43 +04:00
|
|
|
rv =
|
|
|
|
GetSpecialSystemDirectory(Unix_XDG_Download, getter_AddRefs(localFile));
|
2014-05-15 00:15:46 +04:00
|
|
|
*aPersistent = false;
|
2014-05-05 21:30:43 +04:00
|
|
|
}
|
2000-04-21 02:49:18 +04:00
|
|
|
#endif
|
2000-02-22 00:51:47 +03:00
|
|
|
|
2014-05-15 00:15:46 +04:00
|
|
|
if (NS_FAILED(rv)) {
|
2014-05-05 21:30:43 +04:00
|
|
|
return rv;
|
2014-05-15 00:15:46 +04:00
|
|
|
}
|
2000-04-25 05:48:02 +04:00
|
|
|
|
2014-05-15 00:15:46 +04:00
|
|
|
if (!localFile) {
|
2014-05-05 21:30:43 +04:00
|
|
|
return NS_ERROR_FAILURE;
|
2014-05-15 00:15:46 +04:00
|
|
|
}
|
2000-04-25 05:48:02 +04:00
|
|
|
|
2014-05-15 00:15:46 +04:00
|
|
|
localFile.forget(aResult);
|
2014-05-05 21:30:43 +04:00
|
|
|
return NS_OK;
|
2000-02-22 00:51:47 +03:00
|
|
|
}
|
|
|
|
|
2001-11-02 18:29:57 +03:00
|
|
|
NS_IMETHODIMP
|
2014-05-15 00:15:46 +04:00
|
|
|
nsDirectoryService::GetFiles(const char* aProp, nsISimpleEnumerator** aResult) {
|
|
|
|
if (NS_WARN_IF(!aResult)) {
|
2014-05-05 21:30:43 +04:00
|
|
|
return NS_ERROR_INVALID_ARG;
|
2014-05-15 00:15:46 +04:00
|
|
|
}
|
|
|
|
*aResult = nullptr;
|
2014-05-05 21:30:43 +04:00
|
|
|
|
|
|
|
return NS_ERROR_FAILURE;
|
2001-11-02 18:29:57 +03:00
|
|
|
}
|