landing v1.1 patch for 257162 "core changes required to enable XULRunner functionality" r=bsmedberg

This commit is contained in:
darin%meer.net 2004-09-07 18:59:07 +00:00
Родитель a65fe10ff7
Коммит cae8263e6d
10 изменённых файлов: 352 добавлений и 263 удалений

Просмотреть файл

@ -48,6 +48,7 @@
#include "nsChromeRegistry.h"
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsChromeRegistry, Init)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsChromeProtocolHandler)
// The list of components we register
static const nsModuleComponentInfo components[] =
@ -61,7 +62,7 @@ static const nsModuleComponentInfo components[] =
{ "Chrome Protocol Handler",
NS_CHROMEPROTOCOLHANDLER_CID,
NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "chrome",
nsChromeProtocolHandler::Create
nsChromeProtocolHandlerConstructor
}
};

Просмотреть файл

@ -1,4 +1,5 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim:set ts=4 sw=4 sts=4 et cin: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
@ -45,6 +46,7 @@
#include "nsCOMPtr.h"
#include "nsContentCID.h"
#include "nsCRT.h"
#include "nsEventQueueUtils.h"
#include "nsIChannel.h"
#include "nsIChromeRegistry.h"
#include "nsIComponentManager.h"
@ -67,16 +69,13 @@
#include "nsIXULPrototypeCache.h"
#include "nsIXULPrototypeDocument.h"
#endif
#include "nsNetCID.h"
#include "nsNetUtil.h"
#include "nsXPIDLString.h"
#include "nsString.h"
#include "prlog.h"
//----------------------------------------------------------------------
static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
static NS_DEFINE_CID(kStandardURLCID, NS_STANDARDURL_CID);
#ifdef MOZ_XUL
static NS_DEFINE_CID(kXULPrototypeCacheCID, NS_XULPROTOTYPECACHE_CID);
#endif
@ -105,12 +104,12 @@ extern nsIChromeRegistry* gChromeRegistry;
//
// For logging information, NSPR_LOG_MODULES=nsCachedChromeChannel:5
//
#define LOG(args) PR_LOG(gLog, PR_LOG_DEBUG, args)
class nsCachedChromeChannel : public nsIChannel
{
protected:
nsCachedChromeChannel(nsIURI* aURI);
virtual ~nsCachedChromeChannel();
~nsCachedChromeChannel();
nsCOMPtr<nsIURI> mURI;
nsCOMPtr<nsILoadGroup> mLoadGroup;
@ -120,16 +119,10 @@ protected:
nsCOMPtr<nsISupports> mOwner;
nsresult mStatus;
struct LoadEvent {
PLEvent mEvent;
nsCachedChromeChannel* mChannel;
};
static nsresult
static NS_HIDDEN_(nsresult)
PostLoadEvent(nsCachedChromeChannel* aChannel, PLHandleEventProc aHandler);
static void* PR_CALLBACK HandleStartLoadEvent(PLEvent* aEvent);
static void* PR_CALLBACK HandleStopLoadEvent(PLEvent* aEvent);
static void* PR_CALLBACK HandleLoadEvent(PLEvent* aEvent);
static void PR_CALLBACK DestroyLoadEvent(PLEvent* aEvent);
#ifdef PR_LOGGING
@ -137,18 +130,17 @@ protected:
#endif
public:
static nsresult
Create(nsIURI* aURI, nsIChannel** aResult);
nsCachedChromeChannel(nsIURI* aURI);
NS_DECL_ISUPPORTS
// nsIRequest
NS_IMETHOD GetName(nsACString &result) { return NS_ERROR_NOT_IMPLEMENTED; }
NS_IMETHOD IsPending(PRBool *_retval) { *_retval = PR_TRUE; return NS_OK; }
NS_IMETHOD GetName(nsACString &result) { return mURI->GetSpec(result); }
NS_IMETHOD IsPending(PRBool *_retval) { *_retval = (mListener != nsnull); return NS_OK; }
NS_IMETHOD GetStatus(nsresult *status) { *status = mStatus; return NS_OK; }
NS_IMETHOD Cancel(nsresult status) { mStatus = status; return NS_OK; }
NS_IMETHOD Suspend(void) { return NS_OK; }
NS_IMETHOD Resume(void) { return NS_OK; }
NS_IMETHOD Suspend(void) { return NS_OK; } // XXX technically wrong
NS_IMETHOD Resume(void) { return NS_OK; } // XXX technically wrong
NS_IMETHOD GetLoadGroup(nsILoadGroup **);
NS_IMETHOD SetLoadGroup(nsILoadGroup *);
NS_IMETHOD GetLoadFlags(nsLoadFlags *);
@ -167,40 +159,24 @@ NS_IMPL_ISUPPORTS2(nsCachedChromeChannel,
nsIChannel,
nsIRequest)
nsresult
nsCachedChromeChannel::Create(nsIURI* aURI, nsIChannel** aResult)
{
NS_PRECONDITION(aURI != nsnull, "null ptr");
if (! aURI)
return NS_ERROR_NULL_POINTER;
nsCachedChromeChannel* channel = new nsCachedChromeChannel(aURI);
if (! channel)
return NS_ERROR_OUT_OF_MEMORY;
*aResult = channel;
NS_ADDREF(*aResult);
return NS_OK;
}
nsCachedChromeChannel::nsCachedChromeChannel(nsIURI* aURI)
: mURI(aURI), mLoadGroup(nsnull), mLoadFlags (nsIRequest::LOAD_NORMAL), mStatus(NS_OK)
: mURI(aURI)
, mLoadGroup(nsnull)
, mLoadFlags(nsIRequest::LOAD_NORMAL)
, mStatus(NS_OK)
{
#ifdef PR_LOGGING
if (! gLog)
gLog = PR_NewLogModule("nsCachedChromeChannel");
#endif
PR_LOG(gLog, PR_LOG_DEBUG,
("nsCachedChromeChannel[%p]: created", this));
LOG(("nsCachedChromeChannel[%p]: created", this));
}
nsCachedChromeChannel::~nsCachedChromeChannel()
{
PR_LOG(gLog, PR_LOG_DEBUG,
("nsCachedChromeChannel[%p]: destroyed", this));
LOG(("nsCachedChromeChannel[%p]: destroyed", this));
}
@ -241,44 +217,31 @@ nsCachedChromeChannel::Open(nsIInputStream **_retval)
NS_IMETHODIMP
nsCachedChromeChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *ctxt)
{
if (listener) {
NS_ENSURE_ARG_POINTER(listener);
nsresult rv;
if (mLoadGroup) {
PR_LOG(gLog, PR_LOG_DEBUG,
("nsCachedChromeChannel[%p]: adding self to load group %p",
this, mLoadGroup.get()));
rv = mLoadGroup->AddRequest(this, nsnull);
if (NS_FAILED(rv)) return rv;
}
// Fire the OnStartRequest(), which will cause the XUL
// Fire OnStartRequest and OnStopRequest, which will cause the XUL
// document to get embedded.
PR_LOG(gLog, PR_LOG_DEBUG,
("nsCachedChromeChannel[%p]: firing OnStartRequest for %p",
LOG(("nsCachedChromeChannel[%p]: posting load event for %p",
this, listener));
// Queue an event to ourselves to let the stack unwind before
// calling OnStartRequest(). This allows embedding to occur
// before we fire OnStopRequest().
rv = PostLoadEvent(this, HandleStartLoadEvent);
if (NS_FAILED(rv)) {
if (mLoadGroup) {
PR_LOG(gLog, PR_LOG_DEBUG,
("nsCachedChromeChannel[%p]: removing self from load group %p",
this, mLoadGroup.get()));
(void) mLoadGroup->RemoveRequest(this, nsnull, NS_OK);
}
rv = PostLoadEvent(this, HandleLoadEvent);
if (NS_FAILED(rv))
return rv;
}
mContext = ctxt;
mListener = listener;
}
if (mLoadGroup) {
LOG(("nsCachedChromeChannel[%p]: adding self to load group %p",
this, mLoadGroup.get()));
(void) mLoadGroup->AddRequest(this, nsnull);
}
return NS_OK;
}
@ -305,7 +268,7 @@ nsCachedChromeChannel::SetLoadFlags(nsLoadFlags aLoadFlags)
NS_IMETHODIMP
nsCachedChromeChannel::GetOwner(nsISupports * *aOwner)
{
*aOwner = mOwner.get();
*aOwner = mOwner;
NS_IF_ADDREF(*aOwner);
return NS_OK;
}
@ -394,92 +357,55 @@ nsresult
nsCachedChromeChannel::PostLoadEvent(nsCachedChromeChannel* aChannel,
PLHandleEventProc aHandler)
{
nsresult rv;
nsCOMPtr<nsIEventQueueService> svc = do_GetService(kEventQueueServiceCID, &rv);
if (NS_FAILED(rv)) return rv;
if (! svc)
return NS_ERROR_UNEXPECTED;
nsCOMPtr<nsIEventQueue> queue;
rv = svc->GetThreadEventQueue(NS_CURRENT_THREAD, getter_AddRefs(queue));
if (NS_FAILED(rv)) return rv;
nsresult rv = NS_GetCurrentEventQ(getter_AddRefs(queue));
if (NS_FAILED(rv))
return rv;
if (! queue)
return NS_ERROR_UNEXPECTED;
LoadEvent* event = new LoadEvent;
PLEvent* event = new PLEvent;
if (! event)
return NS_ERROR_OUT_OF_MEMORY;
PL_InitEvent(NS_REINTERPRET_CAST(PLEvent*, event),
nsnull,
PL_InitEvent(event,
aChannel,
aHandler,
DestroyLoadEvent);
NS_ADDREF(aChannel);
event->mChannel = aChannel;
NS_ADDREF(event->mChannel);
rv = queue->EnterMonitor();
if (NS_SUCCEEDED(rv)) {
(void) queue->PostEvent(NS_REINTERPRET_CAST(PLEvent*, event));
(void) queue->ExitMonitor();
return NS_OK;
}
// If we get here, something bad happened. Clean up.
NS_RELEASE(event->mChannel);
delete event;
rv = queue->PostEvent(event);
if (NS_FAILED(rv))
PL_DestroyEvent(event);
return rv;
}
void* PR_CALLBACK
nsCachedChromeChannel::HandleStartLoadEvent(PLEvent* aEvent)
nsCachedChromeChannel::HandleLoadEvent(PLEvent* aEvent)
{
// Fire the OnStartRequest() for the cached chrome channel, then
// queue another event to trigger the OnStopRequest()...
LoadEvent* event = NS_REINTERPRET_CAST(LoadEvent*, aEvent);
nsCachedChromeChannel* channel = event->mChannel;
nsCachedChromeChannel* channel = (nsCachedChromeChannel*) aEvent->owner;
// If the load has been cancelled, then just bail now. We won't
// send On[Start|Stop]Request().
if (NS_FAILED(channel->mStatus))
return nsnull;
PR_LOG(gLog, PR_LOG_DEBUG,
("nsCachedChromeChannel[%p]: firing OnStartRequest for %p",
LOG(("nsCachedChromeChannel[%p]: firing OnStartRequest for %p",
channel, channel->mListener.get()));
(void) channel->mListener->OnStartRequest(channel, channel->mContext);
(void) PostLoadEvent(channel, HandleStopLoadEvent);
return nsnull;
}
void* PR_CALLBACK
nsCachedChromeChannel::HandleStopLoadEvent(PLEvent* aEvent)
{
// Fire the OnStopRequest() for the cached chrome channel, and
// remove it from the load group.
LoadEvent* event = NS_REINTERPRET_CAST(LoadEvent*, aEvent);
nsCachedChromeChannel* channel = event->mChannel;
nsIRequest* request = NS_REINTERPRET_CAST(nsIRequest*, channel);
PR_LOG(gLog, PR_LOG_DEBUG,
("nsCachedChromeChannel[%p]: firing OnStopRequest for %p",
LOG(("nsCachedChromeChannel[%p]: firing OnStopRequest for %p",
channel, channel->mListener.get()));
(void) channel->mListener->OnStopRequest(request, channel->mContext,
(void) channel->mListener->OnStopRequest(channel, channel->mContext,
channel->mStatus);
if (channel->mLoadGroup) {
PR_LOG(gLog, PR_LOG_DEBUG,
("nsCachedChromeChannel[%p]: removing self from load group %p",
LOG(("nsCachedChromeChannel[%p]: removing self from load group %p",
channel, channel->mLoadGroup.get()));
(void) channel->mLoadGroup->RemoveRequest(request, nsnull, NS_OK);
(void) channel->mLoadGroup->RemoveRequest(channel, nsnull, channel->mStatus);
}
channel->mListener = nsnull;
@ -491,54 +417,22 @@ nsCachedChromeChannel::HandleStopLoadEvent(PLEvent* aEvent)
void PR_CALLBACK
nsCachedChromeChannel::DestroyLoadEvent(PLEvent* aEvent)
{
LoadEvent* event = NS_REINTERPRET_CAST(LoadEvent*, aEvent);
NS_RELEASE(event->mChannel);
delete event;
nsCachedChromeChannel* channel = (nsCachedChromeChannel*) aEvent->owner;
NS_RELEASE(channel);
delete aEvent;
}
////////////////////////////////////////////////////////////////////////////////
nsChromeProtocolHandler::nsChromeProtocolHandler()
{
}
nsresult
nsChromeProtocolHandler::Init()
{
return NS_OK;
}
nsChromeProtocolHandler::~nsChromeProtocolHandler()
{
}
NS_IMPL_THREADSAFE_ISUPPORTS2(nsChromeProtocolHandler, nsIProtocolHandler, nsISupportsWeakReference)
NS_METHOD
nsChromeProtocolHandler::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
if (aOuter)
return NS_ERROR_NO_AGGREGATION;
nsChromeProtocolHandler* ph = new nsChromeProtocolHandler();
if (ph == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(ph);
nsresult rv = ph->Init();
if (NS_SUCCEEDED(rv)) {
rv = ph->QueryInterface(aIID, aResult);
}
NS_RELEASE(ph);
return rv;
}
////////////////////////////////////////////////////////////////////////////////
// nsIProtocolHandler methods:
NS_IMETHODIMP
nsChromeProtocolHandler::GetScheme(nsACString &result)
{
result = "chrome";
result.AssignLiteral("chrome");
return NS_OK;
}
@ -579,7 +473,7 @@ nsChromeProtocolHandler::NewURI(const nsACString &aSpec,
// Chrome: URLs (currently) have no additional structure beyond that provided
// by standard URLs, so there is no "outer" given to CreateInstance
nsCOMPtr<nsIStandardURL> url(do_CreateInstance(kStandardURLCID, &rv));
nsCOMPtr<nsIStandardURL> url(do_CreateInstance(NS_STANDARDURL_CONTRACTID, &rv));
if (NS_FAILED(rv))
return rv;
@ -677,8 +571,9 @@ nsChromeProtocolHandler::NewChannel(nsIURI* aURI,
if (proto) {
// ...in which case, we'll create a dummy stream that'll just
// load the thing.
rv = nsCachedChromeChannel::Create(aURI, getter_AddRefs(result));
if (NS_FAILED(rv)) return rv;
result = new nsCachedChromeChannel(aURI);
if (! result)
return NS_ERROR_OUT_OF_MEMORY;
}
else
#endif
@ -699,7 +594,7 @@ nsChromeProtocolHandler::NewChannel(nsIURI* aURI,
reg->ConvertChromeURL(aURI, spec);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIIOService> ioServ(do_GetService(kIOServiceCID, &rv));
nsCOMPtr<nsIIOService> ioServ(do_GetIOService(&rv));
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIURI> chromeURI;

Просмотреть файл

@ -58,13 +58,8 @@ public:
NS_DECL_NSIPROTOCOLHANDLER
// nsChromeProtocolHandler methods:
nsChromeProtocolHandler();
virtual ~nsChromeProtocolHandler();
static NS_METHOD
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
nsresult Init();
nsChromeProtocolHandler() {}
~nsChromeProtocolHandler() {}
};
#endif /* nsChromeProtocolHandler_h___ */

Просмотреть файл

@ -3294,64 +3294,115 @@ NS_IMETHODIMP nsChromeRegistry::AllowScriptsForSkin(nsIURI* aChromeURI, PRBool *
return NS_OK;
}
static nsresult
GetFileAndLastModifiedTime(nsIProperties *aDirSvc,
const char *aDirKey,
const nsCSubstring &aLeafName,
nsCOMPtr<nsILocalFile> &aFile,
PRTime *aLastModified)
{
*aLastModified = LL_ZERO;
nsresult rv;
rv = aDirSvc->Get(aDirKey, NS_GET_IID(nsILocalFile), getter_AddRefs(aFile));
if (NS_FAILED(rv))
return rv;
rv = aFile->AppendNative(aLeafName);
if (NS_SUCCEEDED(rv)) {
// if the file does not exist, this returns zero
aFile->GetLastModifiedTime(aLastModified);
}
return rv;
}
NS_IMETHODIMP
nsChromeRegistry::CheckForNewChrome()
{
nsresult rv;
rv = LoadInstallDataSource();
if (NS_FAILED(rv)) return rv;
if (NS_FAILED(rv))
return rv;
// open the installed-chrome file
nsCOMPtr<nsILocalFile> listFile;
nsCOMPtr<nsIProperties> directoryService =
nsCOMPtr<nsIProperties> dirSvc =
do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv);
if (NS_FAILED(rv))
return rv;
rv = directoryService->Get(NS_APP_CHROME_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(listFile));
nsCOMPtr<nsILocalFile> cacheFile, listFile;
nsInt64 cacheDate, listDate;
// check the application directory first.
GetFileAndLastModifiedTime(dirSvc, NS_APP_CHROME_DIR, kChromeFileName,
cacheFile, &cacheDate.mValue);
GetFileAndLastModifiedTime(dirSvc, NS_APP_CHROME_DIR, kInstalledChromeFileName,
listFile, &listDate.mValue);
if (listDate > cacheDate)
ProcessNewChromeFile(listFile);
// check the extra chrome directories
nsCOMPtr<nsISimpleEnumerator> chromeDL;
rv = dirSvc->Get(NS_APP_CHROME_DIR_LIST, NS_GET_IID(nsISimpleEnumerator),
getter_AddRefs(chromeDL));
if (NS_SUCCEEDED(rv)) {
// we assume that any other list files will only reference chrome that
// should be installed in the profile directory. we might want to add
// some actual checks to this effect.
GetFileAndLastModifiedTime(dirSvc, NS_APP_USER_CHROME_DIR, kChromeFileName,
cacheFile, &cacheDate.mValue);
PRBool hasMore;
while (NS_SUCCEEDED(chromeDL->HasMoreElements(&hasMore)) && hasMore) {
nsCOMPtr<nsISupports> element;
chromeDL->GetNext(getter_AddRefs(element));
if (!element)
continue;
listFile = do_QueryInterface(element);
if (!listFile)
continue;
rv = listFile->AppendNative(kInstalledChromeFileName);
if (NS_FAILED(rv))
continue;
listFile->GetLastModifiedTime(&listDate.mValue);
if (listDate > cacheDate)
ProcessNewChromeFile(listFile);
}
}
return rv;
}
nsresult
nsChromeRegistry::ProcessNewChromeFile(nsILocalFile *aListFile)
{
nsresult rv;
PRFileDesc *file;
rv = aListFile->OpenNSPRFileDesc(PR_RDONLY, 0, &file);
if (NS_FAILED(rv))
return rv;
nsCOMPtr<nsIFile> chromeFile;
rv = listFile->Clone(getter_AddRefs(chromeFile));
if (NS_FAILED(rv)) return rv;
rv = chromeFile->AppendNative(kChromeFileName);
if (NS_FAILED(rv)) return rv;
// XXXldb For the case where the file is nonexistent, we're depending
// on the fact that the nsInt64 constructor initializes to 0 and
// |GetLastModifiedTime| doesn't touch the out parameter.
nsInt64 chromeDate;
(void)chromeFile->GetLastModifiedTime(&chromeDate.mValue);
PRInt32 n, size;
char *buf;
rv = listFile->AppendRelativeNativePath(kInstalledChromeFileName);
if (NS_FAILED(rv)) return rv;
nsInt64 listFileDate;
(void)listFile->GetLastModifiedTime(&listFileDate.mValue);
if (listFileDate < chromeDate)
return NS_OK;
PRFileDesc *file;
rv = listFile->OpenNSPRFileDesc(PR_RDONLY, 0, &file);
if (NS_FAILED(rv)) return rv;
// file is open.
PRFileInfo finfo;
if (PR_GetOpenFileInfo(file, &finfo) == PR_SUCCESS) {
char *dataBuffer = new char[finfo.size+1];
if (dataBuffer) {
PRInt32 bufferSize = PR_Read(file, dataBuffer, finfo.size);
if (bufferSize > 0) {
rv = ProcessNewChromeBuffer(dataBuffer, bufferSize);
}
delete [] dataBuffer;
size = PR_Available(file);
if (size == -1) {
rv = NS_ERROR_UNEXPECTED;
goto end;
}
buf = (char *) malloc(size + 1);
if (!buf) {
rv = NS_ERROR_OUT_OF_MEMORY;
goto end;
}
n = PR_Read(file, buf, size);
if (n > 0)
rv = ProcessNewChromeBuffer(buf, size);
free(buf);
end:
PR_Close(file);
// listFile->Remove(PR_FALSE);
return rv;
}

Просмотреть файл

@ -48,6 +48,8 @@ class nsIRDFContainer;
class nsIRDFContainerUtils;
class nsIDOMWindowInternal;
class nsIDocument;
class nsILocalFile;
class nsIProperties;
#include "nsIChromeRegistry.h"
#include "nsIXULOverlayProvider.h"
@ -220,7 +222,8 @@ private:
nsresult UninstallFromDynamicDataSource(const nsACString& aPackageName,
PRBool aIsOverlay, PRBool aUseProfile);
nsresult ProcessNewChromeBuffer(char *aBuffer, PRInt32 aLength);
NS_HIDDEN_(nsresult) ProcessNewChromeFile(nsILocalFile *aListFile);
NS_HIDDEN_(nsresult) ProcessNewChromeBuffer(char *aBuffer, PRInt32 aLength);
PRBool GetProviderCount(const nsACString& aProviderType, nsIRDFDataSource* aDataSource);

Просмотреть файл

@ -161,10 +161,13 @@ nsResProtocolHandler::Init()
//
// make resource://gre/ point to the GRE directory
//
return AddSpecialDir(NS_GRE_DIR, NS_LITERAL_CSTRING("gre"));
rv = AddSpecialDir(NS_GRE_DIR, NS_LITERAL_CSTRING("gre"));
NS_ENSURE_SUCCESS(rv, rv);
//XXXbsmedberg Neil wants a resource://pchrome/ for the profile chrome dir...
// but once I finish multiple chrome registration I'm not sure that it is needed
return rv;
}
//----------------------------------------------------------------------------
@ -265,7 +268,25 @@ nsResProtocolHandler::GetSubstitution(const nsACString& root, nsIURI **result)
{
NS_ENSURE_ARG_POINTER(result);
return mSubstitutions.Get(root, result) ? NS_OK : NS_ERROR_NOT_AVAILABLE;
if (mSubstitutions.Get(root, result))
return NS_OK;
// try invoking the directory service for "resource:root"
nsCAutoString key;
key.AppendLiteral("resource:");
key.Append(root);
nsCOMPtr<nsIFile> file;
nsresult rv = NS_GetSpecialDirectory(key.get(), getter_AddRefs(file));
if (NS_FAILED(rv))
return NS_ERROR_NOT_AVAILABLE;
rv = mIOService->NewFileURI(file, result);
if (NS_FAILED(rv))
return NS_ERROR_NOT_AVAILABLE;
return NS_OK;
}
NS_IMETHODIMP

Просмотреть файл

@ -382,6 +382,70 @@ CheckArg(const char* aArg, const char **aParam = nsnull)
return ARG_NONE;
}
static const nsXREAppData* LoadAppData(const char* appDataFile)
{
static char vendor[256], name[256], version[32], buildID[32], copyright[512];
static const nsXREAppData data = {
vendor, name, version, buildID, copyright, PR_FALSE
};
nsCOMPtr<nsILocalFile> lf;
NS_GetFileFromPath(appDataFile, getter_AddRefs(lf));
if (!lf)
return nsnull;
nsINIParser parser;
if (NS_FAILED(parser.Init(lf)))
return nsnull;
// Ensure that this file specifies a compatible XRE version.
char xreVersion[32];
nsresult rv = parser.GetString("XRE", "Version", xreVersion, sizeof(xreVersion));
if (NS_FAILED(rv) || xreVersion[0] != '0' || xreVersion[1] != '.') {
fprintf(stderr, "Error: XRE version requirement not met.\n");
return nsnull;
}
const struct {
const char* key;
char* buf;
size_t bufLen;
PRBool required;
} fields[] = {
{ "Vendor", vendor, sizeof(vendor), PR_FALSE },
{ "Name", name, sizeof(name), PR_TRUE },
{ "Version", version, sizeof(version), PR_FALSE },
{ "BuildID", buildID, sizeof(buildID), PR_TRUE },
{ "Copyright", copyright, sizeof(copyright), PR_FALSE }
};
for (int i=0; i<5; ++i) {
rv = parser.GetString("App", fields[i].key, fields[i].buf, fields[i].bufLen);
if (NS_FAILED(rv)) {
if (fields[i].required) {
fprintf(stderr, "Error: %x: No \"%s\" field.\n", rv, fields[i].key);
return nsnull;
} else {
fields[i].buf[0] = '\0';
}
}
}
#ifdef DEBUG
printf("---------------------------------------------------------\n");
printf(" Vendor %s\n", data.appVendor);
printf(" Name %s\n", data.appName);
printf(" Version %s\n", data.appVersion);
printf(" BuildID %s\n", data.appBuildID);
printf(" Copyright %s\n", data.copyright);
printf("---------------------------------------------------------\n");
#endif
return &data;
}
static nsresult OpenWindow(const nsAFlatCString& aChromeURL,
const nsAFlatString& aAppArgs,
PRInt32 aWidth, PRInt32 aHeight);
@ -1678,8 +1742,6 @@ int xre_main(int argc, char* argv[], const nsXREAppData* aAppData)
fpsetmask(0);
#endif
gAppData = aAppData;
#if defined(XP_UNIX) && !defined(XP_MACOSX)
if (!GetBinaryPath(argv[0]))
return 1;
@ -1688,6 +1750,17 @@ int xre_main(int argc, char* argv[], const nsXREAppData* aAppData)
gArgc = argc;
gArgv = argv;
// allow -app argument to override default app data
const char *appDataFile = nsnull;
if (CheckArg("app", &appDataFile))
aAppData = LoadAppData(appDataFile);
if (!aAppData) {
fprintf(stderr, "Error: Invalid or missing application data!\n");
return 1;
}
gAppData = aAppData;
gRestartArgc = argc;
gRestartArgv = (char**) malloc(sizeof(char*) * (argc + 1));
if (!gRestartArgv) return 1;
@ -1739,9 +1812,19 @@ int xre_main(int argc, char* argv[], const nsXREAppData* aAppData)
#endif
nsXREDirProvider dirProvider;
rv = dirProvider.Initialize();
{
nsCOMPtr<nsIFile> xulAppDir;
if (appDataFile) {
nsCOMPtr<nsILocalFile> lf;
NS_GetFileFromPath(appDataFile, getter_AddRefs(lf));
lf->GetParent(getter_AddRefs(xulAppDir));
}
rv = dirProvider.Initialize(xulAppDir);
if (NS_FAILED(rv))
return 1;
}
// Check for -register, which registers chrome and then exits immediately.
if (CheckArg("register")) {

Просмотреть файл

@ -101,8 +101,10 @@ nsXREDirProvider::~nsXREDirProvider()
}
nsresult
nsXREDirProvider::Initialize()
nsXREDirProvider::Initialize(nsIFile *aXULAppDir)
{
mXULAppDir = aXULAppDir;
// We need to use platform-specific hackery to find the
// path of this executable. This is copied, with some modifications, from
// nsGREDirServiceProvider.cpp
@ -241,9 +243,9 @@ nsXREDirProvider::GetFile(const char* aProperty, PRBool* aPersistent,
{
rv = mAppDir->Clone(getter_AddRefs(file));
if (NS_SUCCEEDED(rv)) {
rv = file->AppendNative(nsDependentCString("defaults"));
rv = file->AppendNative(NS_LITERAL_CSTRING("defaults"));
if (NS_SUCCEEDED(rv))
rv = file->AppendNative(nsDependentCString("pref"));
rv = file->AppendNative(NS_LITERAL_CSTRING("pref"));
}
}
else if (!strcmp(aProperty, NS_APP_APPLICATION_REGISTRY_DIR)) {
@ -257,20 +259,23 @@ nsXREDirProvider::GetFile(const char* aProperty, PRBool* aPersistent,
rv = GetUserAppDataDirectory((nsILocalFile**)(nsIFile**) getter_AddRefs(file));
#if !defined(XP_UNIX) || defined(XP_MACOSX)
rv |= file->AppendNative(nsDependentCString("Profiles"));
rv |= file->AppendNative(NS_LITERAL_CSTRING("Profiles"));
#endif
// We must create the profile directory here if it does not exist.
rv |= EnsureDirectoryExists(file);
}
else if (mXULAppDir && !strcmp(aProperty, "resource:app")) {
rv = mXULAppDir->Clone(getter_AddRefs(file));
}
else if (mProfileDir) {
if (!strcmp(aProperty, NS_XPCOM_COMPONENT_REGISTRY_FILE)) {
rv = mProfileDir->Clone(getter_AddRefs(file));
rv |= file->AppendNative(nsDependentCString("compreg.dat"));
rv |= file->AppendNative(NS_LITERAL_CSTRING("compreg.dat"));
}
else if (!strcmp(aProperty, NS_XPCOM_XPTI_REGISTRY_FILE)) {
rv = mProfileDir->Clone(getter_AddRefs(file));
rv |= file->AppendNative(nsDependentCString("xpti.dat"));
rv |= file->AppendNative(NS_LITERAL_CSTRING("xpti.dat"));
}
if (mProfileNotified) {
if (!strcmp(aProperty, NS_APP_USER_PROFILE_50_DIR) ||
@ -279,62 +284,62 @@ nsXREDirProvider::GetFile(const char* aProperty, PRBool* aPersistent,
}
else if (!strcmp(aProperty, NS_APP_PREFS_50_FILE)) {
rv = mProfileDir->Clone(getter_AddRefs(file));
rv |= file->AppendNative(nsDependentCString("prefs.js"));
rv |= file->AppendNative(NS_LITERAL_CSTRING("prefs.js"));
}
// XXXbsmedberg this needs rethinking... many of these are app-specific,
// and apps are going to add new stuff. I don't have a good solution,
// yet.
else if (!strcmp(aProperty, NS_APP_USER_CHROME_DIR)) {
rv = mProfileDir->Clone(getter_AddRefs(file));
rv |= file->AppendNative(nsDependentCString("chrome"));
rv |= file->AppendNative(NS_LITERAL_CSTRING("chrome"));
}
else if (!strcmp(aProperty, NS_APP_LOCALSTORE_50_FILE)) {
rv = mProfileDir->Clone(getter_AddRefs(file));
rv |= file->AppendNative(nsDependentCString("localstore.rdf"));
rv |= file->AppendNative(NS_LITERAL_CSTRING("localstore.rdf"));
EnsureProfileFileExists(file);
}
else if (!strcmp(aProperty, NS_APP_HISTORY_50_FILE)) {
rv = mProfileDir->Clone(getter_AddRefs(file));
rv |= file->AppendNative(nsDependentCString("history.dat"));
rv |= file->AppendNative(NS_LITERAL_CSTRING("history.dat"));
}
else if (!strcmp(aProperty, NS_APP_USER_PANELS_50_FILE)) {
rv = mProfileDir->Clone(getter_AddRefs(file));
rv |= file->AppendNative(nsDependentCString("panels.rdf"));
rv |= file->AppendNative(NS_LITERAL_CSTRING("panels.rdf"));
EnsureProfileFileExists(file);
}
else if (!strcmp(aProperty, NS_APP_USER_MIMETYPES_50_FILE)) {
rv = mProfileDir->Clone(getter_AddRefs(file));
rv |= file->AppendNative(nsDependentCString("mimeTypes.rdf"));
rv |= file->AppendNative(NS_LITERAL_CSTRING("mimeTypes.rdf"));
EnsureProfileFileExists(file);
}
else if (!strcmp(aProperty, NS_APP_BOOKMARKS_50_FILE)) {
rv = mProfileDir->Clone(getter_AddRefs(file));
rv |= file->AppendNative(nsDependentCString("bookmarks.html"));
rv |= file->AppendNative(NS_LITERAL_CSTRING("bookmarks.html"));
}
else if (!strcmp(aProperty, NS_APP_DOWNLOADS_50_FILE)) {
rv = mProfileDir->Clone(getter_AddRefs(file));
rv |= file->AppendNative(nsDependentCString("downloads.rdf"));
rv |= file->AppendNative(NS_LITERAL_CSTRING("downloads.rdf"));
}
else if (!strcmp(aProperty, NS_APP_SEARCH_50_FILE)) {
rv = mProfileDir->Clone(getter_AddRefs(file));
rv |= file->AppendNative(nsDependentCString("search.rdf"));
rv |= file->AppendNative(NS_LITERAL_CSTRING("search.rdf"));
EnsureProfileFileExists(file);
}
else if (!strcmp(aProperty, NS_APP_MAIL_50_DIR)) {
rv = mProfileDir->Clone(getter_AddRefs(file));
rv |= file->AppendNative(nsDependentCString("Mail"));
rv |= file->AppendNative(NS_LITERAL_CSTRING("Mail"));
}
else if (!strcmp(aProperty, NS_APP_IMAP_MAIL_50_DIR)) {
rv = mProfileDir->Clone(getter_AddRefs(file));
rv |= file->AppendNative(nsDependentCString("ImapMail"));
rv |= file->AppendNative(NS_LITERAL_CSTRING("ImapMail"));
}
else if (!strcmp(aProperty, NS_APP_NEWS_50_DIR)) {
rv = mProfileDir->Clone(getter_AddRefs(file));
rv |= file->AppendNative(nsDependentCString("News"));
rv |= file->AppendNative(NS_LITERAL_CSTRING("News"));
}
else if (!strcmp(aProperty, NS_APP_MESSENGER_FOLDER_CACHE_50_DIR)) {
rv = mProfileDir->Clone(getter_AddRefs(file));
rv |= file->AppendNative(nsDependentCString("panacea.dat"));
rv |= file->AppendNative(NS_LITERAL_CSTRING("panacea.dat"));
}
}
}
@ -390,15 +395,24 @@ nsXREDirProvider::GetFiles(const char* aProperty, nsISimpleEnumerator** aResult)
if (mRegisterExtraComponents) {
nsCOMArray<nsIFile> directories;
if (mXULAppDir) {
nsCOMPtr<nsIFile> file;
mXULAppDir->Clone(getter_AddRefs(file));
file->AppendNative(NS_LITERAL_CSTRING("components"));
PRBool exists;
if (NS_SUCCEEDED(file->Exists(&exists)) && exists)
directories.AppendObject(file);
}
nsCOMPtr<nsIFile> appFile;
mAppDir->Clone(getter_AddRefs(appFile));
appFile->AppendNative(nsDependentCString("components.ini"));
appFile->AppendNative(NS_LITERAL_CSTRING("components.ini"));
LoadDirsIntoArray(appFile, directories);
nsCOMPtr<nsIFile> profileFile;
if (mProfileDir) {
mProfileDir->Clone(getter_AddRefs(profileFile));
profileFile->AppendNative(nsDependentCString("components.ini"));
profileFile->AppendNative(NS_LITERAL_CSTRING("components.ini"));
LoadDirsIntoArray(profileFile, directories);
}
@ -408,20 +422,44 @@ nsXREDirProvider::GetFiles(const char* aProperty, nsISimpleEnumerator** aResult)
else if (!strcmp(aProperty, NS_APP_PREFS_DEFAULTS_DIR_LIST)) {
nsCOMArray<nsIFile> directories;
if (mXULAppDir) {
nsCOMPtr<nsIFile> file;
mXULAppDir->Clone(getter_AddRefs(file));
file->AppendNative(NS_LITERAL_CSTRING("defaults"));
file->AppendNative(NS_LITERAL_CSTRING("pref"));
PRBool exists;
if (NS_SUCCEEDED(file->Exists(&exists)) && exists)
directories.AppendObject(file);
}
nsCOMPtr<nsIFile> appFile;
mAppDir->Clone(getter_AddRefs(appFile));
appFile->AppendNative(nsDependentCString("defaults.ini"));
appFile->AppendNative(NS_LITERAL_CSTRING("defaults.ini"));
LoadDirsIntoArray(appFile, directories);
nsCOMPtr<nsIFile> profileFile;
if (mProfileDir) {
mProfileDir->Clone(getter_AddRefs(profileFile));
profileFile->AppendNative(nsDependentCString("defaults.ini"));
profileFile->AppendNative(NS_LITERAL_CSTRING("defaults.ini"));
LoadDirsIntoArray(profileFile, directories);
}
rv = NS_NewArrayEnumerator(aResult, directories);
}
else if (!strcmp(aProperty, NS_APP_CHROME_DIR_LIST)) {
nsCOMArray<nsIFile> directories;
if (mXULAppDir) {
nsCOMPtr<nsIFile> file;
mXULAppDir->Clone(getter_AddRefs(file));
file->AppendNative(NS_LITERAL_CSTRING("chrome"));
PRBool exists;
if (NS_SUCCEEDED(file->Exists(&exists)) && exists)
directories.AppendObject(file);
}
rv = NS_NewArrayEnumerator(aResult, directories);
}
else
rv = NS_ERROR_FAILURE;
@ -728,8 +766,8 @@ nsXREDirProvider::GetProfileDefaultsDir(nsIFile* *aResult)
rv = mAppDir->Clone(getter_AddRefs(defaultsDir));
NS_ENSURE_SUCCESS(rv, rv);
rv = defaultsDir->AppendNative(nsDependentCString("defaults"));
rv |= defaultsDir->AppendNative(nsDependentCString("profile"));
rv = defaultsDir->AppendNative(NS_LITERAL_CSTRING("defaults"));
rv |= defaultsDir->AppendNative(NS_LITERAL_CSTRING("profile"));
NS_ENSURE_SUCCESS(rv, rv);
NS_ADDREF(*aResult = defaultsDir);

Просмотреть файл

@ -57,7 +57,7 @@ public:
NS_DECL_NSIPROFILESTARTUP
nsXREDirProvider();
nsresult Initialize();
nsresult Initialize(nsIFile *aXULAppDir);
~nsXREDirProvider();
// We only set the profile dir, we don't ensure that it exists;
@ -86,6 +86,7 @@ protected:
void EnsureProfileFileExists(nsIFile* aFile);
nsCOMPtr<nsILocalFile> mAppDir;
nsCOMPtr<nsIFile> mXULAppDir;
nsCOMPtr<nsIFile> mProfileDir;
PRBool mProfileNotified;
PRBool mRegisterExtraComponents;

Просмотреть файл

@ -76,6 +76,7 @@
#define NS_APP_PLUGINS_DIR "APlugns" // Deprecated - use NS_APP_PLUGINS_DIR_LIST
#define NS_APP_SEARCH_DIR "SrchPlugns"
#define NS_APP_CHROME_DIR_LIST "AChromDL"
#define NS_APP_PLUGINS_DIR_LIST "APluginsDL"
// --------------------------------------------------------------------------------------