зеркало из https://github.com/mozilla/gecko-dev.git
Bug 105440 - directory service needs new keys and be able to support lists of directories. r=valeski/sr=jband
This commit is contained in:
Родитель
1908bdafba
Коммит
ea7a6dcd37
|
@ -44,6 +44,11 @@
|
|||
// Defines property names for directories available from standard nsIDirectoryServiceProviders.
|
||||
// These keys are not guaranteed to exist because the nsIDirectoryServiceProviders which
|
||||
// provide them are optional.
|
||||
//
|
||||
// Keys whose definition ends in "DIR" or "FILE" return a single nsIFile (or subclass).
|
||||
// Keys whose definition ends in "LIST" return an nsISimpleEnumerator which enumerates a
|
||||
// list of file objects.
|
||||
//
|
||||
// System and XPCOM level properties are defined in nsDirectoryServiceDefs.h.
|
||||
//
|
||||
//========================================================================================
|
||||
|
@ -68,9 +73,11 @@
|
|||
|
||||
#define NS_APP_RES_DIR "ARes"
|
||||
#define NS_APP_CHROME_DIR "AChrom"
|
||||
#define NS_APP_PLUGINS_DIR "APlugns"
|
||||
#define NS_APP_PLUGINS_DIR "APlugns" // Deprecated - use NS_APP_PLUGINS_DIR_LIST
|
||||
#define NS_APP_SEARCH_DIR "SrchPlugns"
|
||||
|
||||
#define NS_APP_PLUGINS_DIR_LIST "APluginsDL"
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// Files and directories which exist on a per-profile basis
|
||||
// These locations are typically provided by the profile mgr
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "nsILocalFile.h"
|
||||
#include "nsString.h"
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsISimpleEnumerator.h"
|
||||
|
||||
#if defined(XP_MAC) /* || defined(XP_MACOSX) REMIND HACKING FOR MACOS X!!! */
|
||||
#include <Folders.h>
|
||||
|
@ -109,7 +110,7 @@ nsAppFileLocationProvider::~nsAppFileLocationProvider()
|
|||
// nsAppFileLocationProvider::nsISupports
|
||||
//*****************************************************************************
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS1(nsAppFileLocationProvider, nsIDirectoryServiceProvider)
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS2(nsAppFileLocationProvider, nsIDirectoryServiceProvider, nsIDirectoryServiceProvider2)
|
||||
|
||||
//*****************************************************************************
|
||||
// nsAppFileLocationProvider::nsIDirectoryServiceProvider
|
||||
|
@ -121,6 +122,7 @@ nsAppFileLocationProvider::GetFile(const char *prop, PRBool *persistant, nsIFile
|
|||
nsCOMPtr<nsILocalFile> localFile;
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
|
||||
NS_ENSURE_ARG(prop);
|
||||
*_retval = nsnull;
|
||||
*persistant = PR_TRUE;
|
||||
|
||||
|
@ -346,3 +348,84 @@ NS_METHOD nsAppFileLocationProvider::GetDefaultUserProfileRoot(nsILocalFile **aL
|
|||
return rv;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
// nsAppFileLocationProvider::nsIDirectoryServiceProvider2
|
||||
//*****************************************************************************
|
||||
|
||||
class nsAppDirectoryEnumerator : public nsISimpleEnumerator
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
/**
|
||||
* aKeyList is a list of properties which are provided by aProvider
|
||||
* They do not need to be publicly defined keys.
|
||||
*/
|
||||
nsAppDirectoryEnumerator(nsIDirectoryServiceProvider *aProvider,
|
||||
const char* aKeyList[],
|
||||
PRInt32 aNumKeys) :
|
||||
mProvider(aProvider),
|
||||
mKeyList(aKeyList),
|
||||
mCurrentIndex(0), mMaxIndex(aNumKeys)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
}
|
||||
|
||||
NS_IMETHOD HasMoreElements(PRBool *result)
|
||||
{
|
||||
*result = (mCurrentIndex < mMaxIndex) &&
|
||||
(mKeyList && mKeyList[mCurrentIndex]);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHOD GetNext(nsISupports **result)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(result);
|
||||
*result = nsnull;
|
||||
|
||||
PRBool hasMore;
|
||||
HasMoreElements(&hasMore);
|
||||
if (!hasMore)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
PRBool dontCare;
|
||||
nsCOMPtr<nsIFile> newFile;
|
||||
nsresult rv = mProvider->GetFile(mKeyList[mCurrentIndex++], &dontCare, getter_AddRefs(newFile));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
*result = newFile;
|
||||
NS_ADDREF(*result);
|
||||
|
||||
return *result ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
~nsAppDirectoryEnumerator() // I don't expect to be subclassed
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
nsIDirectoryServiceProvider *mProvider;
|
||||
const char** mKeyList;
|
||||
PRInt32 mCurrentIndex, mMaxIndex;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsAppDirectoryEnumerator, nsISimpleEnumerator)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAppFileLocationProvider::GetFiles(const char *prop, nsISimpleEnumerator **_retval)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(_retval);
|
||||
*_retval = nsnull;
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
|
||||
if (!nsCRT::strcmp(prop, NS_APP_PLUGINS_DIR_LIST))
|
||||
{
|
||||
static const char* keys[] = { NS_APP_PLUGINS_DIR };
|
||||
|
||||
*_retval = new nsAppDirectoryEnumerator(this, keys, sizeof(keys) / sizeof(keys[0]));
|
||||
NS_IF_ADDREF(*_retval);
|
||||
rv = *_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
|
|
@ -31,13 +31,14 @@ class nsIFile;
|
|||
// class nsAppFileLocationProvider
|
||||
//*****************************************************************************
|
||||
|
||||
class nsAppFileLocationProvider : public nsIDirectoryServiceProvider
|
||||
class nsAppFileLocationProvider : public nsIDirectoryServiceProvider2
|
||||
{
|
||||
public:
|
||||
nsAppFileLocationProvider();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIDIRECTORYSERVICEPROVIDER
|
||||
NS_DECL_NSIDIRECTORYSERVICEPROVIDER2
|
||||
|
||||
protected:
|
||||
virtual ~nsAppFileLocationProvider();
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#include <Files.h>
|
||||
#include <Memory.h>
|
||||
#include <Processes.h>
|
||||
#include <Gestalt.h>
|
||||
#ifdef XP_MACOSX
|
||||
#include "prenv.h"
|
||||
#endif
|
||||
|
@ -583,7 +584,7 @@ nsDirectoryService::~nsDirectoryService()
|
|||
|
||||
}
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS3(nsDirectoryService, nsIProperties, nsIDirectoryService, nsIDirectoryServiceProvider)
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS4(nsDirectoryService, nsIProperties, nsIDirectoryService, nsIDirectoryServiceProvider, nsIDirectoryServiceProvider2)
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -603,26 +604,45 @@ nsDirectoryService::Undefine(const char* prop)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
typedef struct FileData
|
||||
|
||||
struct FileData
|
||||
{
|
||||
const char* property;
|
||||
nsIFile* file;
|
||||
PRBool persistent;
|
||||
|
||||
} FileData;
|
||||
FileData(const char* aProperty,
|
||||
const nsIID& aUUID) :
|
||||
property(aProperty),
|
||||
data(nsnull),
|
||||
persistent(PR_TRUE),
|
||||
uuid(aUUID) {}
|
||||
|
||||
const char* property;
|
||||
nsISupports* data;
|
||||
PRBool persistent;
|
||||
const nsIID& uuid;
|
||||
};
|
||||
|
||||
static PRBool FindProviderFile(nsISupports* aElement, void *aData)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIDirectoryServiceProvider> prov = do_QueryInterface(aElement);
|
||||
if (!prov)
|
||||
return PR_FALSE;
|
||||
|
||||
FileData* fileData = (FileData*)aData;
|
||||
rv = prov->GetFile(fileData->property, &fileData->persistent, &(fileData->file) );
|
||||
if (NS_SUCCEEDED(rv) && fileData->file)
|
||||
return PR_FALSE;
|
||||
if (fileData->uuid.Equals(NS_GET_IID(nsISimpleEnumerator)))
|
||||
{
|
||||
// Not all providers implement this iface
|
||||
nsCOMPtr<nsIDirectoryServiceProvider2> prov2 = do_QueryInterface(aElement);
|
||||
if (prov2)
|
||||
{
|
||||
rv = prov2->GetFiles(fileData->property, (nsISimpleEnumerator **)&fileData->data);
|
||||
if (NS_SUCCEEDED(rv) && fileData->data)
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
nsCOMPtr<nsIDirectoryServiceProvider> prov = do_QueryInterface(aElement);
|
||||
if (!prov)
|
||||
return PR_FALSE;
|
||||
rv = prov->GetFile(fileData->property, &fileData->persistent, (nsIFile **)&fileData->data);
|
||||
if (NS_SUCCEEDED(rv) && fileData->data)
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
@ -647,32 +667,29 @@ nsDirectoryService::Get(const char* prop, const nsIID & uuid, void* *result)
|
|||
}
|
||||
|
||||
// it is not one of our defaults, lets check any providers
|
||||
FileData fileData;
|
||||
fileData.property = prop;
|
||||
fileData.file = nsnull;
|
||||
fileData.persistent = PR_TRUE;
|
||||
FileData fileData(prop, uuid);
|
||||
|
||||
mProviders->EnumerateForwards(FindProviderFile, &fileData);
|
||||
if (fileData.file)
|
||||
if (fileData.data)
|
||||
{
|
||||
if (fileData.persistent)
|
||||
{
|
||||
Set(prop, NS_STATIC_CAST(nsIFile*, fileData.file));
|
||||
Set(prop, NS_STATIC_CAST(nsIFile*, fileData.data));
|
||||
}
|
||||
nsresult rv = (fileData.file)->QueryInterface(uuid, result);
|
||||
NS_RELEASE(fileData.file); // addref occurs in FindProviderFile()
|
||||
nsresult rv = (fileData.data)->QueryInterface(uuid, result);
|
||||
NS_RELEASE(fileData.data); // addref occurs in FindProviderFile()
|
||||
return rv;
|
||||
}
|
||||
|
||||
FindProviderFile(NS_STATIC_CAST(nsIDirectoryServiceProvider*, this), &fileData);
|
||||
if (fileData.file)
|
||||
if (fileData.data)
|
||||
{
|
||||
if (fileData.persistent)
|
||||
{
|
||||
Set(prop, NS_STATIC_CAST(nsIFile*, fileData.file));
|
||||
Set(prop, NS_STATIC_CAST(nsIFile*, fileData.data));
|
||||
}
|
||||
nsresult rv = (fileData.file)->QueryInterface(uuid, result);
|
||||
NS_RELEASE(fileData.file); // addref occurs in FindProviderFile()
|
||||
nsresult rv = (fileData.data)->QueryInterface(uuid, result);
|
||||
NS_RELEASE(fileData.data); // addref occurs in FindProviderFile()
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -1079,6 +1096,121 @@ nsDirectoryService::GetFile(const char *prop, PRBool *persistent, nsIFile **_ret
|
|||
return rv;
|
||||
}
|
||||
|
||||
#if defined (XP_MAC)
|
||||
|
||||
struct FindFolderParms
|
||||
{
|
||||
short vRefNumOrDomain;
|
||||
OSType folderType;
|
||||
};
|
||||
|
||||
class nsSystemDirEnumeratorMac : public nsISimpleEnumerator
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
nsSystemDirEnumeratorMac(const FindFolderParms aFolderList[],
|
||||
PRInt32 aListCount) :
|
||||
mFolderList(aFolderList),
|
||||
mCurrentIndex(0), mMaxIndex(aListCount)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
}
|
||||
|
||||
NS_IMETHOD HasMoreElements(PRBool *result)
|
||||
{
|
||||
*result = ((mCurrentIndex < mMaxIndex) && mFolderList);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHOD GetNext(nsISupports **result)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(result);
|
||||
*result = nsnull;
|
||||
|
||||
PRBool hasMore;
|
||||
HasMoreElements(&hasMore);
|
||||
if (!hasMore)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
OSErr err;
|
||||
short foundVRefNum;
|
||||
long foundDirID;
|
||||
FSSpec fileSpec;
|
||||
|
||||
const FindFolderParms *currentFolder = mFolderList + mCurrentIndex++;
|
||||
err = ::FindFolder(currentFolder->vRefNumOrDomain,
|
||||
currentFolder->folderType,
|
||||
kDontCreateFolder, &foundVRefNum, &foundDirID);
|
||||
if (err == noErr)
|
||||
err = ::FSMakeFSSpec(foundVRefNum, foundDirID, "\p", &fileSpec);
|
||||
if (err != noErr)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsILocalFileMac> newFile;
|
||||
nsresult rv = NS_NewLocalFileWithFSSpec(&fileSpec, PR_TRUE, getter_AddRefs(newFile));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
*result = newFile;
|
||||
NS_ADDREF(*result);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
~nsSystemDirEnumeratorMac() // I don't expect to be subclassed
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
const FindFolderParms *mFolderList;
|
||||
PRInt32 mCurrentIndex, mMaxIndex;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsSystemDirEnumeratorMac, nsISimpleEnumerator)
|
||||
#endif // XP_MAC
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDirectoryService::GetFiles(const char *prop, nsISimpleEnumerator **_retval)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(_retval);
|
||||
*_retval = nsnull;
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
|
||||
if (!nsCRT::strcmp(prop, NS_OS_PLUGINS_DIR_LIST))
|
||||
{
|
||||
#if defined(XP_MAC)
|
||||
static const FindFolderParms sClassicPluginsList[] = {
|
||||
{ kOnAppropriateDisk, kInternetPlugInFolderType}
|
||||
};
|
||||
|
||||
const FindFolderParms *parmList;
|
||||
PRInt32 parmListSize;
|
||||
|
||||
#if TARGET_CARBON
|
||||
static const FindFolderParms sOSXPluginsList[] = {
|
||||
{ kUserDomain, kInternetPlugInFolderType },
|
||||
{ kLocalDomain, kInternetPlugInFolderType }
|
||||
};
|
||||
|
||||
OSErr err;
|
||||
long response;
|
||||
err = ::Gestalt(gestaltSystemVersion, &response);
|
||||
if (!err && response >= 0x00001000)
|
||||
{
|
||||
parmList = sOSXPluginsList;
|
||||
parmListSize = sizeof(sOSXPluginsList) / sizeof(sOSXPluginsList[0]);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
parmList = sClassicPluginsList;
|
||||
parmListSize = sizeof(sClassicPluginsList) / sizeof(sClassicPluginsList[0]);
|
||||
}
|
||||
*_retval = new nsSystemDirEnumeratorMac(parmList, parmListSize);
|
||||
NS_IF_ADDREF(*_retval);
|
||||
rv = *_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
||||
#endif // XP_MAC
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
|
|
@ -46,7 +46,9 @@
|
|||
#include "nsXPIDLString.h"
|
||||
|
||||
|
||||
class nsDirectoryService : public nsIDirectoryService, public nsIProperties, public nsIDirectoryServiceProvider
|
||||
class nsDirectoryService : public nsIDirectoryService,
|
||||
public nsIProperties,
|
||||
public nsIDirectoryServiceProvider2
|
||||
{
|
||||
public:
|
||||
|
||||
|
@ -60,6 +62,8 @@ class nsDirectoryService : public nsIDirectoryService, public nsIProperties, pub
|
|||
NS_DECL_NSIDIRECTORYSERVICE
|
||||
|
||||
NS_DECL_NSIDIRECTORYSERVICEPROVIDER
|
||||
|
||||
NS_DECL_NSIDIRECTORYSERVICEPROVIDER2
|
||||
|
||||
nsDirectoryService();
|
||||
virtual ~nsDirectoryService();
|
||||
|
|
|
@ -45,6 +45,9 @@
|
|||
// dirs are always available even if no nsIDirectoryServiceProviders have been registered
|
||||
// with the service. Application level keys are defined in nsAppDirectoryServiceDefs.h.
|
||||
//
|
||||
// Keys whose definition ends in "DIR" or "FILE" return a single nsIFile (or subclass).
|
||||
// Keys whose definition ends in "LIST" return an nsISimpleEnumerator which enumerates a
|
||||
// list of file objects.
|
||||
//========================================================================================
|
||||
|
||||
|
||||
|
@ -66,6 +69,8 @@
|
|||
#define NS_OS_SYSTEM_DIR "SysD"
|
||||
#endif
|
||||
|
||||
#define NS_OS_PLUGINS_DIR_LIST "OSPluginsDL"
|
||||
|
||||
// for MacOSX we need the UNIX entries, plus the MAC entries
|
||||
#if defined (XP_UNIX) || defined(XP_MACOSX)
|
||||
#define NS_UNIX_LOCAL_DIR "Locl"
|
||||
|
@ -113,7 +118,7 @@
|
|||
#define NS_WIN_COMMON_STARTUP_DIR "CmStrt"
|
||||
#define NS_WIN_COMMON_DESKTOP_DIRECTORY "CmDeskP"
|
||||
#define NS_WIN_APPDATA_DIR "AppData"
|
||||
#define NS_WIN_PRINTHOOD "PrntHd"
|
||||
#define NS_WIN_PRINTHOOD "PrntHd"
|
||||
#elif defined (XP_OS2)
|
||||
#define NS_OS2_DIR "OS2Dir"
|
||||
#define NS_OS2_HOME_DIR "Home"
|
||||
|
|
|
@ -39,21 +39,99 @@
|
|||
#include "nsIFile.idl"
|
||||
|
||||
/**
|
||||
* nsIDirectoryServiceProvider
|
||||
*
|
||||
* Used by Directory Service to get file locations.
|
||||
*
|
||||
* @status FROZEN
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
[scriptable, uuid(bbf8cab0-d43a-11d3-8cc2-00609792278c)]
|
||||
interface nsIDirectoryServiceProvider: nsISupports
|
||||
{
|
||||
nsIFile getFile(in string prop, out PRBool persistant);
|
||||
/**
|
||||
* getFile
|
||||
*
|
||||
* Directory Service calls this when it gets the first request for
|
||||
* a prop or on every request if the prop is not persistent.
|
||||
*
|
||||
* @param prop The symbolic name of the file.
|
||||
* @param persistent TRUE - The returned file will be cached by Directory
|
||||
* Service. Subsequent requests for this prop will
|
||||
* bypass the provider and use the cache.
|
||||
* FALSE - The provider will be asked for this prop
|
||||
* each time it is requested.
|
||||
*
|
||||
* @return The file represented by the property.
|
||||
*
|
||||
*/
|
||||
nsIFile getFile(in string prop, out PRBool persistent);
|
||||
};
|
||||
|
||||
/**
|
||||
* nsIDirectoryServiceProvider2
|
||||
*
|
||||
* An extension of nsIDirectoryServiceProvider which allows
|
||||
* multiple files to be returned for the given key.
|
||||
*
|
||||
* @status UNDER_REVIEW
|
||||
*/
|
||||
|
||||
[scriptable, uuid(2f977d4b-5485-11d4-87e2-0010a4e75ef2)]
|
||||
interface nsIDirectoryServiceProvider2: nsIDirectoryServiceProvider
|
||||
{
|
||||
/**
|
||||
* getFiles
|
||||
*
|
||||
* Directory Service calls this when it gets a request for
|
||||
* a prop and the requested type is nsISimpleEnumerator.
|
||||
*
|
||||
* @param prop The symbolic name of the file list.
|
||||
*
|
||||
* @return An enumerator for a list of file locations.
|
||||
* The elements in the enumeration are nsIFile
|
||||
*
|
||||
*/
|
||||
nsISimpleEnumerator getFiles(in string prop);
|
||||
};
|
||||
|
||||
/**
|
||||
* nsIDirectoryService
|
||||
*
|
||||
* @status FROZEN
|
||||
*/
|
||||
|
||||
[scriptable, uuid(57a66a60-d43a-11d3-8cc2-00609792278c)]
|
||||
interface nsIDirectoryService: nsISupports
|
||||
{
|
||||
/**
|
||||
* init
|
||||
*
|
||||
* Must be called. Used internally by XPCOM initialization.
|
||||
*
|
||||
*/
|
||||
void init();
|
||||
|
||||
/**
|
||||
* registerProvider
|
||||
*
|
||||
* Register a provider with the service.
|
||||
*
|
||||
* @param prov The service will keep a strong reference
|
||||
* to this object. It will be released when
|
||||
* the service is released.
|
||||
*
|
||||
*/
|
||||
void registerProvider(in nsIDirectoryServiceProvider prov);
|
||||
|
||||
/**
|
||||
* unregisterProvider
|
||||
*
|
||||
* Unregister a provider with the service.
|
||||
*
|
||||
* @param prov
|
||||
*
|
||||
*/
|
||||
void unregisterProvider(in nsIDirectoryServiceProvider prov);
|
||||
};
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче