Bug 223900 - Clean up MFCEmbed to use the GRE properly (don't link against xpcom.dll), and make the GRE glue libs more embedder-friendly and flexible. r=adamlock/dougt sr=dougt

This commit is contained in:
bsmedberg%covad.net 2003-11-17 06:13:49 +00:00
parent 0851395ebe
commit a888a82d0b
10 changed files with 414 additions and 402 deletions

View File

@ -38,6 +38,15 @@ PROGRAM = mfcembed$(BIN_SUFFIX)
RESFILE = MfcEmbed.res
MODULE = mfcEmbed
# comment this out if for some reason you want to link against xpcom
# directly instead of using the standalone glue
GRE_BUILD = 1
ifdef GRE_BUILD
DEFINES += -DXPCOM_GLUE
endif
REQUIRES = \
xpcom_obsolete \
xpcom \
@ -97,7 +106,7 @@ CPPSRCS = \
StdAfx.cpp \
$(NULL)
EXTRA_DSO_LIBS = embed_base_s profdirserviceprovider_s gkgfx mfcEmbedComponents
EXTRA_DSO_LIBS = embed_base_s profdirserviceprovider_s
ifdef NS_TRACE_MALLOC
EXTRA_DSO_LIBS += tracemalloc
@ -106,11 +115,20 @@ endif
LIBS = \
$(EXTRA_DSO_LIBS) \
$(MOZ_UNICHARUTIL_LIBS) \
$(XPCOM_LIBS) \
$(NSPR_LIBS) \
$(MOZ_JS_LIBS) \
$(NULL)
ifdef GRE_BUILD
LIBS += \
$(DIST)/lib/$(LIB_PREFIX)string_s.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)string_obsolete_s.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)xpcomglue.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)embedstring_s.$(LIB_SUFFIX) \
$(NULL)
else
LIBS += $(XPCOM_LIBS)
endif
OS_LIBS += \
ole32.lib \
comdlg32.lib \

View File

@ -47,6 +47,8 @@
// Local Includes
#include "stdafx.h"
#include "MfcEmbed.h"
#include "nsXPCOMGlue.h"
#include "nsIComponentRegistrar.h"
#include "BrowserFrm.h"
#include "EditorFrm.h"
#include "winEmbedFileLocProvider.h"
@ -54,7 +56,6 @@
#include "nsIWindowWatcher.h"
#include "plstr.h"
#include "Preferences.h"
#include "nsCRT.h"
#include <io.h>
#include <fcntl.h>
@ -250,8 +251,10 @@ CMfcEmbedApp theApp;
*/
nsresult CMfcEmbedApp::OverrideComponents()
{
nsresult rv = NS_OK;
nsCOMPtr<nsIComponentRegistrar> compReg;
nsresult rv = NS_GetComponentRegistrar(getter_AddRefs(compReg));
NS_ENSURE_SUCCESS(rv, rv);
// replace Mozilla's default PromptService with our own, if the
// expected override DLL is present
HMODULE overlib = ::LoadLibrary(kComponentsLibname);
@ -266,12 +269,12 @@ nsresult CMfcEmbedApp::OverrideComponents()
nsCOMPtr<nsIFactory> promptFactory;
rv = MakeFactory(getter_AddRefs(promptFactory));
if (NS_SUCCEEDED(rv))
nsComponentManager::RegisterFactory(kPromptServiceCID,
"Prompt Service",
"@mozilla.org/embedcomp/prompt-service;1",
promptFactory,
PR_TRUE); // replace existing
if (NS_SUCCEEDED(rv)) {
compReg->RegisterFactory(kPromptServiceCID,
"Prompt Service",
"@mozilla.org/embedcomp/prompt-service;1",
promptFactory);
}
} else
::FreeLibrary(overlib);
}
@ -290,11 +293,10 @@ nsresult CMfcEmbedApp::OverrideComponents()
nsCOMPtr<nsIFactory> helperAppDlgFactory;
rv = MakeFactory(getter_AddRefs(helperAppDlgFactory));
if (NS_SUCCEEDED(rv))
nsComponentManager::RegisterFactory(kHelperAppLauncherDialogCID,
"Helper App Launcher Dialog",
"@mozilla.org/helperapplauncherdialog;1",
helperAppDlgFactory,
PR_TRUE); // replace existing
compReg->RegisterFactory(kHelperAppLauncherDialogCID,
"Helper App Launcher Dialog",
"@mozilla.org/helperapplauncherdialog;1",
helperAppDlgFactory);
} else
::FreeLibrary(overlib);
}
@ -314,11 +316,10 @@ nsresult CMfcEmbedApp::OverrideComponents()
nsCOMPtr<nsIFactory> printingPromptFactory;
rv = MakeFactory(getter_AddRefs(printingPromptFactory));
if (NS_SUCCEEDED(rv))
nsComponentManager::RegisterFactory(kPrintingPromptServiceCID,
"Printing Prompt Service",
"@mozilla.org/embedcomp/printingprompt-service;1",
printingPromptFactory,
PR_TRUE); // replace existing
compReg->RegisterFactory(kPrintingPromptServiceCID,
"Printing Prompt Service",
"@mozilla.org/embedcomp/printingprompt-service;1",
printingPromptFactory);
} else
::FreeLibrary(overlib);
}
@ -382,27 +383,40 @@ BOOL CMfcEmbedApp::InitInstance()
NSGetStaticModuleInfo = app_getModuleInfo;
#endif
CMfcEmbedCommandLine cmdLine(*this);
ParseCommandLine(cmdLine);
Enable3dControls();
#ifdef XPCOM_GLUE
if (NS_FAILED(XPCOMGlueStartup(GRE_GetXPCOMPath()))) {
MessageBox(NULL, "Could not initialize XPCOM. Perhaps the GRE\nis not installed or could not be found?", "MFCEmbed", MB_OK | MB_ICONERROR);
return FALSE;
}
#endif
//
// 1. Determine the name of the dir from which the GRE based app is being run
// from [It's OK to do this even if you're not running in an GRE env]
//
// 2. Create an nsILocalFile out of it which will passed in to NS_InitEmbedding()
//
// Please see http://www.mozilla.org/projects/embedding/MRE.html
// Please see http://www.mozilla.org/projects/embedding/GRE.html
// for more info. on GRE
TCHAR curDir[_MAX_PATH+1];
::GetCurrentDirectory(_MAX_PATH, curDir);
TCHAR path[_MAX_PATH+1];
::GetModuleFileName(0, path, _MAX_PATH);
TCHAR* lastSlash = _tcsrchr(path, _T('\\'));
if (!lastSlash) {
NS_ERROR("No slash in module file name... something is wrong.");
return FALSE;
}
*lastSlash = _T('\0');
USES_CONVERSION;
nsresult rv;
nsCOMPtr<nsILocalFile> mreAppDir;
rv = NS_NewNativeLocalFile(nsDependentCString(T2A(curDir)), TRUE, getter_AddRefs(mreAppDir));
rv = NS_NewNativeLocalFile(nsDependentCString(T2A(path)), TRUE, getter_AddRefs(mreAppDir));
NS_ASSERTION(NS_SUCCEEDED(rv), "failed to create mreAppDir localfile");
// Take a look at
@ -589,6 +603,10 @@ int CMfcEmbedApp::ExitInstance()
NS_TermEmbedding();
#ifdef XPCOM_GLUE
XPCOMGlueShutdown();
#endif
return 1;
}
@ -798,7 +816,7 @@ NS_IMETHODIMP CMfcEmbedApp::Observe(nsISupports *aSubject, const char *aTopic, c
{
nsresult rv = NS_OK;
if (nsCRT::strcmp(aTopic, "profile-approve-change") == 0)
if (strcmp(aTopic, "profile-approve-change") == 0)
{
// Ask the user if they want to
int result = MessageBox(NULL,
@ -811,7 +829,7 @@ NS_IMETHODIMP CMfcEmbedApp::Observe(nsISupports *aSubject, const char *aTopic, c
status->VetoChange();
}
}
else if (nsCRT::strcmp(aTopic, "profile-change-teardown") == 0)
else if (strcmp(aTopic, "profile-change-teardown") == 0)
{
// Close all open windows. Alternatively, we could just call CBrowserWindow::Stop()
// on each. Either way, we have to stop all network activity on this phase.
@ -832,13 +850,13 @@ NS_IMETHODIMP CMfcEmbedApp::Observe(nsISupports *aSubject, const char *aTopic, c
}
}
}
else if (nsCRT::strcmp(aTopic, "profile-after-change") == 0)
else if (strcmp(aTopic, "profile-after-change") == 0)
{
InitializePrefs(); // In case we have just switched to a newly created profile.
// Only make a new browser window on a switch. This also gets
// called at start up and we already make a window then.
if (!nsCRT::strcmp(someData, NS_LITERAL_STRING("switch").get()))
if (!wcscmp(someData, NS_LITERAL_STRING("switch").get()))
OnNewBrowser();
}
return rv;

View File

@ -38,7 +38,6 @@
// Mozilla
#include "nsIProfile.h"
#include "nsIServiceManager.h"
#include "nsCRT.h"
#ifdef _DEBUG
#define new DEBUG_NEW
@ -227,7 +226,7 @@ BOOL CProfilesDlg::OnInitDialog()
{
CString tmpStr(W2T(profileList[index]));
m_ProfileList.AddString(tmpStr);
if (nsCRT::strcmp(profileList[index], curProfileName.get()) == 0)
if (wcscmp(profileList[index], curProfileName.get()) == 0)
selectedRow = index;
}

View File

@ -26,16 +26,17 @@
*
* Contributor(s):
* Conrad Carlen <conrad@ingress.com>
* Benjamin Smedberg <bsmedberg@covad.net>
*
* ***** END LICENSE BLOCK ***** */
#include "winEmbedFileLocProvider.h"
#include "nsXPCOMGlue.h"
#include "nsAppDirectoryServiceDefs.h"
#include "nsDirectoryServiceDefs.h"
#include "nsILocalFile.h"
#include "nsString.h"
#include "nsXPIDLString.h"
#include "nsCRT.h"
#include <windows.h>
@ -89,23 +90,23 @@ winEmbedFileLocProvider::GetFile(const char *prop, PRBool *persistant, nsIFile *
*_retval = nsnull;
*persistant = PR_TRUE;
if (nsCRT::strcmp(prop, NS_APP_APPLICATION_REGISTRY_DIR) == 0)
if (strcmp(prop, NS_APP_APPLICATION_REGISTRY_DIR) == 0)
{
rv = GetProductDirectory(getter_AddRefs(localFile));
}
else if (nsCRT::strcmp(prop, NS_APP_APPLICATION_REGISTRY_FILE) == 0)
else if (strcmp(prop, NS_APP_APPLICATION_REGISTRY_FILE) == 0)
{
rv = GetProductDirectory(getter_AddRefs(localFile));
if (NS_SUCCEEDED(rv))
rv = localFile->AppendNative(APP_REGISTRY_NAME);
}
else if (nsCRT::strcmp(prop, NS_APP_DEFAULTS_50_DIR) == 0)
else if (strcmp(prop, NS_APP_DEFAULTS_50_DIR) == 0)
{
rv = CloneMozBinDirectory(getter_AddRefs(localFile));
if (NS_SUCCEEDED(rv))
rv = localFile->AppendRelativeNativePath(DEFAULTS_DIR_NAME);
}
else if (nsCRT::strcmp(prop, NS_APP_PREF_DEFAULTS_50_DIR) == 0)
else if (strcmp(prop, NS_APP_PREF_DEFAULTS_50_DIR) == 0)
{
rv = CloneMozBinDirectory(getter_AddRefs(localFile));
if (NS_SUCCEEDED(rv)) {
@ -114,8 +115,8 @@ winEmbedFileLocProvider::GetFile(const char *prop, PRBool *persistant, nsIFile *
rv = localFile->AppendRelativeNativePath(DEFAULTS_PREF_DIR_NAME);
}
}
else if (nsCRT::strcmp(prop, NS_APP_PROFILE_DEFAULTS_NLOC_50_DIR) == 0 ||
nsCRT::strcmp(prop, NS_APP_PROFILE_DEFAULTS_50_DIR) == 0)
else if (strcmp(prop, NS_APP_PROFILE_DEFAULTS_NLOC_50_DIR) == 0 ||
strcmp(prop, NS_APP_PROFILE_DEFAULTS_50_DIR) == 0)
{
rv = CloneMozBinDirectory(getter_AddRefs(localFile));
if (NS_SUCCEEDED(rv)) {
@ -124,53 +125,50 @@ winEmbedFileLocProvider::GetFile(const char *prop, PRBool *persistant, nsIFile *
rv = localFile->AppendRelativeNativePath(DEFAULTS_PROFILE_DIR_NAME);
}
}
else if (nsCRT::strcmp(prop, NS_APP_USER_PROFILES_ROOT_DIR) == 0)
else if (strcmp(prop, NS_APP_USER_PROFILES_ROOT_DIR) == 0)
{
rv = GetDefaultUserProfileRoot(getter_AddRefs(localFile));
}
else if (nsCRT::strcmp(prop, NS_APP_RES_DIR) == 0)
else if (strcmp(prop, NS_APP_RES_DIR) == 0)
{
rv = CloneMozBinDirectory(getter_AddRefs(localFile));
if (NS_SUCCEEDED(rv))
rv = localFile->AppendRelativeNativePath(RES_DIR_NAME);
}
else if (nsCRT::strcmp(prop, NS_APP_CHROME_DIR) == 0)
else if (strcmp(prop, NS_APP_CHROME_DIR) == 0)
{
rv = CloneMozBinDirectory(getter_AddRefs(localFile));
if (NS_SUCCEEDED(rv))
rv = localFile->AppendRelativeNativePath(CHROME_DIR_NAME);
}
else if (nsCRT::strcmp(prop, NS_APP_PLUGINS_DIR) == 0)
else if (strcmp(prop, NS_APP_PLUGINS_DIR) == 0)
{
rv = CloneMozBinDirectory(getter_AddRefs(localFile));
if (NS_SUCCEEDED(rv))
rv = localFile->AppendRelativeNativePath(PLUGINS_DIR_NAME);
}
else if (nsCRT::strcmp(prop, NS_APP_SEARCH_DIR) == 0)
else if (strcmp(prop, NS_APP_SEARCH_DIR) == 0)
{
rv = CloneMozBinDirectory(getter_AddRefs(localFile));
if (NS_SUCCEEDED(rv))
rv = localFile->AppendRelativeNativePath(SEARCH_DIR_NAME);
}
#ifdef XPCOM_GLUE
//---------------------------------------------------------------
// Note that by returning a valid localFile's for NS_GRE_DIR and
// NS_GRE_COMPONENT_DIR your app is indicating to XPCOM that
// it found an GRE version with which it's compatible with and
// it intends to be "run against" that GRE
//
// Please see http://www.mozilla.org/projects/embedding/MRE.html
// Please see http://www.mozilla.org/projects/embedding/GRE.html
// for more info. on GRE
//---------------------------------------------------------------
else if (nsCRT::strcmp(prop, NS_GRE_DIR) == 0)
else if (strcmp(prop, NS_GRE_DIR) == 0)
{
rv = GetGreDirectory(getter_AddRefs(localFile));
}
else if (nsCRT::strcmp(prop, NS_GRE_COMPONENT_DIR) == 0)
{
rv = GetGreDirectory(getter_AddRefs(localFile));
if (NS_SUCCEEDED(rv))
rv = localFile->AppendRelativeNativePath(COMPONENTS_DIR_NAME);
}
rv = GRE_GetGREDirectory(getter_AddRefs(localFile));
}
#endif
if (localFile && NS_SUCCEEDED(rv))
return localFile->QueryInterface(NS_GET_IID(nsIFile), (void**)_retval);
@ -178,87 +176,6 @@ winEmbedFileLocProvider::GetFile(const char *prop, PRBool *persistant, nsIFile *
return rv;
}
// Get the location of the GRE version we're compatible with from
// the registry
//
char * winEmbedFileLocProvider::GetGreLocationFromRegistry()
{
char szKey[256];
HKEY hRegKey = NULL;
DWORD dwLength = _MAX_PATH * sizeof(char);
long rc;
char keyValue[_MAX_PATH + 1];
char *pGreLocation = NULL;
// A couple of key points here:
// 1. Note the usage of the "Software\\Mozilla\\GRE" subkey - this allows
// us to have multiple versions of GREs on the same machine by having
// subkeys such as 1.0, 1.1, 2.0 etc. under it.
// 2. In this sample below we're looking for the location of GRE version 1.2
// i.e. we're compatible with GRE 1.2 and we're trying to find it's install
// location.
//
// Please see http://www.mozilla.org/projects/embedding/MRE.html for
// more info.
//
strcpy(szKey, "Software\\mozilla.org\\GRE\\" MOZILLA_VERSION);
if (::RegOpenKeyEx(HKEY_LOCAL_MACHINE, szKey, 0, KEY_QUERY_VALUE, &hRegKey) == ERROR_SUCCESS)
{
if ((rc = ::RegQueryValueEx(hRegKey, "GreHome", NULL, NULL, (BYTE *)keyValue, &dwLength))==ERROR_SUCCESS)
{
pGreLocation = ::strdup(keyValue);
::RegCloseKey(hRegKey);
}
}
return pGreLocation;
}
// Create and return the location of the GRE the application is
// currently using, if any, via the |aLocalFile| param
//
// If an embedding application is written to use an GRE it determines
// the compatible GRE's location by looking in the Windows registry
// In this case GetGreDirectory() creates a new localFile based on the
// GRE path it just read from the registry
//
// If the embedding appliction is not using an GRE and is running in
// a "regular" embedding scenario GetGreDirectory() simply returns a
// failure code indicating to the caller to fallback to a non-GRE
// based operation - which is the default mode of operation.
//
// Please see http://www.mozilla.org/projects/embedding/MRE.html for
// more information on the Gecko Runtime Environment(GRE) and for
// the actual registry key whichs contains the GRE path, if any.
NS_METHOD winEmbedFileLocProvider::GetGreDirectory(nsILocalFile **aLocalFile)
{
NS_ENSURE_ARG_POINTER(aLocalFile);
nsresult rv = NS_ERROR_FAILURE;
// Get the path of the GRE which is compatible with our embedding application
// from the registry
//
char *pGreDir = GetGreLocationFromRegistry();
if(pGreDir)
{
nsCOMPtr<nsILocalFile> tempLocal;
rv = NS_NewNativeLocalFile(nsDependentCString(pGreDir), TRUE, getter_AddRefs(tempLocal));
if (tempLocal)
{
*aLocalFile = tempLocal;
NS_ADDREF(*aLocalFile);
rv = NS_OK;
}
::free(pGreDir);
}
return rv;
}
NS_METHOD winEmbedFileLocProvider::CloneMozBinDirectory(nsILocalFile **aLocalFile)
{
NS_ENSURE_ARG_POINTER(aLocalFile);

View File

@ -49,15 +49,12 @@ public:
NS_DECL_ISUPPORTS
NS_DECL_NSIDIRECTORYSERVICEPROVIDER
static char * GetGreLocationFromRegistry();
protected:
virtual ~winEmbedFileLocProvider();
NS_METHOD CloneMozBinDirectory(nsILocalFile **aLocalFile);
NS_METHOD GetProductDirectory(nsILocalFile **aLocalFile);
NS_METHOD GetDefaultUserProfileRoot(nsILocalFile **aLocalFile);
NS_METHOD GetGreDirectory(nsILocalFile **aLocalFile);
nsCString mProductDirName;

View File

@ -120,7 +120,7 @@ NS_GetFrozenFunctions(XPCOMFunctions *entryPoints, const char* libraryPath);
*
* XPCOM_DLL - name of the loadable xpcom library on disk.
* XPCOM_SEARCH_KEY - name of the environment variable that can be
* modified to include additional search paths.
* modified to include additional search paths.
* GRE_CONF_NAME - Name of the GRE Configuration file
*/
@ -131,13 +131,6 @@ NS_GetFrozenFunctions(XPCOMFunctions *entryPoints, const char* libraryPath);
#define GRE_WIN_REG_LOC "Software\\mozilla.org\\GRE\\"
#define XPCOM_DLL "xpcom.dll"
#elif defined(XP_MAC)
#define XPCOM_SEARCH_KEY "PATH"
#define GRE_CONF_NAME "gre.config"
#define GRE_CONF_PATH ":Macintosh HD:gre.conf"
#define XPCOM_DLL "xpcom.shlb"
#elif defined(XP_BEOS)
#define XPCOM_SEARCH_KEY "ADDON_PATH"
@ -161,14 +154,12 @@ NS_GetFrozenFunctions(XPCOMFunctions *entryPoints, const char* libraryPath);
#define GRE_CONF_DIR "/etc/gre.d/"
#endif
#if defined(XP_MAC)
#define XPCOM_FILE_PATH_SEPARATOR ":"
#elif defined(XP_WIN) || defined(XP_OS2)
#if defined(XP_WIN) || defined(XP_OS2)
#define XPCOM_FILE_PATH_SEPARATOR "\\"
#define XPCOM_ENV_PATH_SEPARATOR ";"
#elif defined(XP_UNIX) || defined(XP_BEOS)
#define XPCOM_FILE_PATH_SEPARATOR "/"
#define XPCOM_ENV_PATH_SEPARATOR ":"
#else
#error need_to_define_your_file_path_separator_and_illegal_characters
#endif

View File

@ -1,3 +1,4 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
@ -40,9 +41,13 @@
#include "nsGREDirServiceProvider.h"
#include "nsEmbedString.h"
#include "nsXPCOMPrivate.h"
#include "nsXPCOMGlue.h"
#include "nsILocalFile.h"
#include "nsIDirectoryService.h"
#include "nsDirectoryServiceDefs.h"
#include "nsCOMPtr.h"
#include "nspr.h"
#include "prenv.h"
#include "plstr.h"
#ifdef XP_WIN32
@ -73,24 +78,11 @@
#include "prenv.h"
#endif
#include <sys/stat.h>
//*****************************************************************************
// greEmbedFileLocProvider::Constructor/Destructor
//*****************************************************************************
nsGREDirServiceProvider::nsGREDirServiceProvider()
: mPathEnvString(nsnull)
{
AddGRELocationToPath();
}
nsGREDirServiceProvider::~nsGREDirServiceProvider()
{
if (mPathEnvString)
PR_smprintf_free(mPathEnvString);
}
PRBool GRE_GetCurrentProcessDirectory(char* buffer);
PRBool GRE_GetPathFromConfigDir(const char* dirname, char* buffer);
PRBool GRE_GetPathFromConfigFile(const char* dirname, char* buffer);
//*****************************************************************************
// nsGREDirServiceProvider::nsISupports
@ -122,31 +114,34 @@ nsGREDirServiceProvider::GetFile(const char *prop, PRBool *persistant, nsIFile *
//---------------------------------------------------------------
if(strcmp(prop, NS_GRE_DIR) == 0)
{
rv = GetGreDirectory(getter_AddRefs(localFile));
rv = GRE_GetGREDirectory(getter_AddRefs(localFile));
}
if(!localFile || NS_FAILED(rv))
return rv;
NS_ENSURE_SUCCESS(rv, rv);
if (!localFile)
return NS_ERROR_UNEXPECTED;
return localFile->QueryInterface(NS_GET_IID(nsIFile), (void**)_retval);
}
//*****************************************************************************
// Implementations from nsXPCOMGlue.h and helper functions.
//*****************************************************************************
static
char* GetCurrentProcessDirectory()
PRBool
GRE_GetCurrentProcessDirectory(char* buffer)
{
char* resultPath = nsnull;
*buffer = '\0';
#ifdef XP_WIN
char buf[MAX_PATH];
if ( ::GetModuleFileName(0, buf, sizeof(buf)) ) {
if ( ::GetModuleFileName(0, buffer, MAXPATHLEN) ) {
// chop of the executable name by finding the rightmost backslash
char* lastSlash = PL_strrchr(buf, '\\');
if (lastSlash)
char* lastSlash = PL_strrchr(buffer, '\\');
if (lastSlash) {
*(lastSlash) = '\0';
resultPath = strdup(buf);
return resultPath;
return PR_TRUE;
}
}
#elif defined(XP_MACOSX)
@ -163,19 +158,16 @@ char* GetCurrentProcessDirectory()
CFStringRef path = CFURLCopyFileSystemPath(parentURL, kCFURLPOSIXPathStyle);
if (path)
{
char buffer[512];
if (CFStringGetCString(path, buffer, sizeof(buffer), kCFStringEncodingUTF8))
{
resultPath = strdup(buffer);
}
CFStringGetCString(path, buffer, MAXPATHLEN, kCFStringEncodingUTF8);
CFRelease(path);
}
CFRelease(parentURL);
}
CFRelease(bundleURL);
}
CFRelease(appBundle);
}
return resultPath;
if (*buffer) return PR_TRUE;
#elif defined(XP_UNIX)
@ -183,7 +175,6 @@ char* GetCurrentProcessDirectory()
// us try this for unix:
// - if MOZILLA_FIVE_HOME is defined, that is it
// - else give the current directory
char buf[MAXPATHLEN];
// The MOZ_DEFAULT_MOZILLA_FIVE_HOME variable can be set at configure time with
// a --with-default-mozilla-five-home=foo autoconf flag.
@ -203,13 +194,12 @@ char* GetCurrentProcessDirectory()
char *moz5 = PR_GetEnv("MOZILLA_FIVE_HOME");
if (moz5)
if (moz5 && *moz5)
{
if (realpath(moz5, buf))
resultPath = strdup(buf);
else
resultPath = strdup(moz5);
return resultPath;
if (!realpath(moz5, buffer))
strcpy(buffer, moz5);
return PR_TRUE;
}
else
{
@ -224,132 +214,144 @@ char* GetCurrentProcessDirectory()
#endif /* DEBUG */
// Fall back to current directory.
if (getcwd(buf, sizeof(buf)))
if (getcwd(buffer, MAXPATHLEN))
{
resultPath = strdup(buf);
return resultPath;
return PR_TRUE;
}
}
#elif defined(XP_OS2)
PPIB ppib;
PTIB ptib;
char buffer[CCHMAXPATH];
char* p;
DosGetInfoBlocks( &ptib, &ppib);
DosQueryModuleName( ppib->pib_hmte, CCHMAXPATH, buffer);
DosQueryModuleName( ppib->pib_hmte, MAXPATHLEN, buffer);
p = strrchr( buffer, '\\'); // XXX DBCS misery
if (p)
if (p) {
*p = '\0';
resultPath = strdup(buffer);
return resultPath;
return PR_TRUE;
}
#elif defined(XP_BEOS)
char *moz5 = getenv("MOZILLA_FIVE_HOME");
if (moz5)
{
resultPath = strdup(moz5);
return resultPath;
strcpy(buffer, moz5);
return PR_TRUE;
}
else
{
static char buf[MAXPATHLEN];
int32 cookie = 0;
image_info info;
char *p;
*buf = 0;
if(get_next_image_info(0, &cookie, &info) == B_OK)
{
strcpy(buf, info.name);
if((p = strrchr(buf, '/')) != 0)
strcpy(buffer, info.name);
if((p = strrchr(buffer, '/')) != 0)
{
*p = 0;
resultPath = strdup(buf);
return resultPath;
return PR_TRUE;
}
}
}
#endif
return nsnull;
return PR_FALSE;
}
/**
* the GRE location is stored in a static buffer so that we don't have
* to compute it multiple times.
*/
// Get the location of the GRE version we're compatible with from
// the registry
//
char *
nsGREDirServiceProvider::GetGREDirectoryPath()
static char sGRELocation[MAXPATHLEN] = "";
extern "C" char const *
GRE_GetGREPath()
{
char *pGreLocation = nsnull;
// If the xpcom library exists in the current process directory,
// then we will not use any GRE. The assumption here is that the GRE is in the
// same directory as the executable.
char* cpd = GetCurrentProcessDirectory();
if (cpd) {
char* xpcomLibPath= (char *)malloc(strlen(cpd) + sizeof(XPCOM_DLL) + sizeof(XPCOM_FILE_PATH_SEPARATOR));
sprintf(xpcomLibPath, "%s" XPCOM_FILE_PATH_SEPARATOR XPCOM_DLL, cpd);
// we've already done this...
if (*sGRELocation)
return sGRELocation;
struct stat libStat;
int statResult = stat(xpcomLibPath, &libStat);
free (xpcomLibPath);
char buffer[MAXPATHLEN];
// If the xpcom library exists in the current process directory,
// then we will not use any GRE. The assumption here is that the
// GRE is in the same directory as the executable.
if (GRE_GetCurrentProcessDirectory(buffer)) {
PRUint32 pathlen = strlen(buffer);
strcpy(buffer + pathlen, XPCOM_FILE_PATH_SEPARATOR XPCOM_DLL);
struct stat libStat;
int statResult = stat(buffer, &libStat);
if (statResult != -1) {
//found our xpcom lib in the current process directory
return cpd;
buffer[pathlen] = '\0';
strcpy(sGRELocation, buffer);
return sGRELocation;
}
free(cpd);
}
// if GRE_HOME is in the environment, use that GRE
const char* env = PR_GetEnv("GRE_HOME");
if (env && *env) {
#if XP_UNIX
if (!realpath(env, sGRELocation))
strcpy(sGRELocation, env);
#elif XP_WIN32
if (!_fullpath(sGRELocation, env, MAXPATHLEN))
strcpy(sGRELocation, env);
#endif
// xxxbsmedberg: it would help that other platforms had a "make absolute" function
return sGRELocation;
}
// the Gecko bits that sit next to the application or in the LD_LIBRARY_PATH
if (PR_GetEnv("USE_LOCAL_GRE"))
env = PR_GetEnv("USE_LOCAL_GRE");
if (env && *env)
return nsnull;
#if XP_UNIX
// check in the HOME directory
char * path = PR_GetEnv("HOME");
if (path) {
char* greConfHomePath= (char *)malloc(strlen(path) + sizeof(GRE_CONF_NAME) + sizeof(XPCOM_FILE_PATH_SEPARATOR));
env = PR_GetEnv("HOME");
if (env && *env) {
sprintf(buffer, "%s" XPCOM_FILE_PATH_SEPARATOR GRE_CONF_NAME, env);
sprintf(greConfHomePath, "%s" XPCOM_FILE_PATH_SEPARATOR GRE_CONF_NAME, path);
pGreLocation = GetPathFromConfigFile(greConfHomePath);
free(greConfHomePath);
if (pGreLocation)
return pGreLocation;
if (GRE_GetPathFromConfigFile(buffer, sGRELocation)) {
return sGRELocation;
}
}
path = PR_GetEnv("MOZ_GRE_CONF");
if (path) {
pGreLocation = GetPathFromConfigFile(path);
if (pGreLocation)
return pGreLocation;
#endif
env = PR_GetEnv("MOZ_GRE_CONF");
if (env) {
if (GRE_GetPathFromConfigFile(env, sGRELocation)) {
return sGRELocation;
}
}
#ifdef XP_UNIX
#if XP_UNIX
// Look for a group of config files in /etc/gre.d/
pGreLocation = GetPathFromConfigDir(GRE_CONF_DIR);
if (pGreLocation)
return pGreLocation;
if (GRE_GetPathFromConfigDir(GRE_CONF_DIR, sGRELocation)) {
return sGRELocation;
}
// Look for a global /etc/gre.conf file
pGreLocation = GetPathFromConfigFile(GRE_CONF_PATH);
if (pGreLocation)
return pGreLocation;
if (GRE_GetPathFromConfigFile(GRE_CONF_PATH, sGRELocation)) {
return sGRELocation;
}
#endif
#if XP_WIN32
char szKey[256];
HKEY hRegKey = NULL;
DWORD dwLength = _MAX_PATH * sizeof(char);
long rc;
char keyValue[_MAX_PATH + 1];
DWORD dwLength = MAXPATHLEN;
// A couple of key points here:
// 1. Note the usage of the "Software\\Mozilla\\GRE" subkey - this allows
// us to have multiple versions of GREs on the same machine by having
@ -358,25 +360,37 @@ nsGREDirServiceProvider::GetGREDirectoryPath()
// i.e. we're compatible with GRE 1.2 and we're trying to find it's install
// location.
//
// Please see http://www.mozilla.org/projects/embedding/MRE.html for
// Please see http://www.mozilla.org/projects/embedding/GE.html for
// more info.
//
strcpy(szKey, GRE_WIN_REG_LOC GRE_BUILD_ID);
if (::RegOpenKeyEx(HKEY_LOCAL_MACHINE, szKey, 0, KEY_QUERY_VALUE, &hRegKey) == ERROR_SUCCESS) {
if ((rc = ::RegQueryValueEx(hRegKey, "GreHome", NULL, NULL, (BYTE *)keyValue, &dwLength))==ERROR_SUCCESS) {
pGreLocation = strdup(keyValue);
if (::RegOpenKeyEx(HKEY_CURRENT_USER, szKey, 0, KEY_QUERY_VALUE, &hRegKey) == ERROR_SUCCESS) {
if (::RegQueryValueEx(hRegKey, "GreHome", NULL, NULL, (BYTE *)sGRELocation, &dwLength) != ERROR_SUCCESS) {
*sGRELocation = '\0';
}
::RegCloseKey(hRegKey);
if (*sGRELocation)
return sGRELocation;
}
if (::RegOpenKeyEx(HKEY_LOCAL_MACHINE, szKey, 0, KEY_QUERY_VALUE, &hRegKey) == ERROR_SUCCESS) {
if (::RegQueryValueEx(hRegKey, "GreHome", NULL, NULL, (BYTE *)sGRELocation, &dwLength) != ERROR_SUCCESS) {
*sGRELocation = '\0';
}
::RegCloseKey(hRegKey);
if (*sGRELocation)
return sGRELocation;
}
if (pGreLocation)
return pGreLocation;
#endif
return pGreLocation;
return nsnull;
}
char*
nsGREDirServiceProvider::GetPathFromConfigDir(const char* dirname)
PRBool
GRE_GetPathFromConfigDir(const char* dirname, char* buffer)
{
// Open the directory provided and try to read any files in that
// directory that end with .conf. We look for an entry that might
@ -385,10 +399,10 @@ nsGREDirServiceProvider::GetPathFromConfigDir(const char* dirname)
if (!dir)
return nsnull;
char *pGreLocation = nsnull;
PRBool found = PR_FALSE;
PRDirEntry *entry;
while (!pGreLocation && (entry = PR_ReadDir(dir, PR_SKIP_BOTH))) {
while (!found && (entry = PR_ReadDir(dir, PR_SKIP_BOTH))) {
// Only look for files that end in .conf
char *offset = PL_strrstr(entry->name, ".conf");
@ -400,26 +414,26 @@ nsGREDirServiceProvider::GetPathFromConfigDir(const char* dirname)
nsEmbedCString fullPath;
fullPath += dirname;
fullPath += "/";
fullPath += XPCOM_FILE_PATH_SEPARATOR;
fullPath += entry->name;
pGreLocation = GetPathFromConfigFile(fullPath.get());
found = GRE_GetPathFromConfigFile(fullPath.get(), buffer);
}
PR_CloseDir(dir);
return pGreLocation;
return found;
}
char*
nsGREDirServiceProvider::GetPathFromConfigFile(const char* filename)
PRBool
GRE_GetPathFromConfigFile(const char* filename, char* pathBuffer)
{
char* pGreLocation = nsnull;
*pathBuffer = '\0';
char buffer[1024];
FILE *cfg;
PRBool foundHeader = PR_FALSE;
PRInt32 versionLen = sizeof(MOZILLA_VERSION)-1;
PRInt32 versionLen = sizeof(GRE_BUILD_ID)-1;
if((cfg=fopen(filename,"r"))==nsnull) {
return nsnull;
}
@ -429,116 +443,69 @@ nsGREDirServiceProvider::GetPathFromConfigFile(const char* filename)
if (buffer[0] == '#' || buffer[0] == '\n') {
continue;
}
// we found a section heading, check to see if it is the one we are intersted in.
if (buffer[0] == '[') {
if (!strncmp (buffer+1, MOZILLA_VERSION, versionLen)) {
if (!strncmp (buffer+1, GRE_BUILD_ID, versionLen)) {
foundHeader = PR_TRUE;
}
continue;
}
if (foundHeader && !strncmp (buffer, "GRE_PATH=", 9)) {
pGreLocation = strdup(buffer + 9 );
strcpy(pathBuffer, buffer + 9);
// kill the line feed if any
PRInt32 len = strlen(pGreLocation);
PRInt32 len = strlen(pathBuffer);
len--;
if (pGreLocation[len] == '\n')
pGreLocation[len] = '\0';
if (pathBuffer[len] == '\n')
pathBuffer[len] = '\0';
break;
}
}
fclose(cfg);
return pGreLocation;
return (*pathBuffer != '\0');
}
nsresult
nsGREDirServiceProvider::GetGreDirectory(nsILocalFile **aLocalFile)
extern "C" nsresult
GRE_GetGREDirectory(nsILocalFile* *_retval)
{
NS_ENSURE_ARG_POINTER(aLocalFile);
NS_ENSURE_ARG_POINTER(_retval);
nsresult rv = NS_ERROR_FAILURE;
// Get the path of the GRE which is compatible with our embedding application
// from the registry
//
char *pGreDir = GetGREDirectoryPath();
if(pGreDir) {
const char *pGREDir = GRE_GetGREPath();
if(pGREDir) {
nsCOMPtr<nsILocalFile> tempLocal;
nsEmbedCString leaf;
leaf.Assign(pGreDir);
leaf.Assign(pGREDir);
rv = NS_NewNativeLocalFile(leaf, PR_TRUE, getter_AddRefs(tempLocal));
if (NS_SUCCEEDED(rv)) {
*aLocalFile = tempLocal;
NS_ADDREF(*aLocalFile);
*_retval = tempLocal;
NS_ADDREF(*_retval);
}
free(pGreDir);
}
return rv;
}
static char sXPCOMPath[MAXPATHLEN];
char*
nsGREDirServiceProvider::GetXPCOMPath()
extern "C" const char*
GRE_GetXPCOMPath()
{
char* grePath = GetGREDirectoryPath();
const char* grePath = GRE_GetGREPath();
if (!grePath) {
char* greEnv = PR_GetEnv("MOZILLA_FIVE_HOME");
if (!greEnv) {
grePath = PR_GetEnv("MOZILLA_FIVE_HOME");
if (!grePath || !*grePath) {
return nsnull;
}
grePath = strdup(greEnv);
}
int len = strlen(grePath);
char* xpcomPath = (char*) malloc(len + sizeof(XPCOM_DLL) + sizeof(XPCOM_FILE_PATH_SEPARATOR) + 1);
sprintf(sXPCOMPath, "%s" XPCOM_FILE_PATH_SEPARATOR XPCOM_DLL, grePath);
sprintf(xpcomPath, "%s" XPCOM_FILE_PATH_SEPARATOR XPCOM_DLL, grePath);
free(grePath);
return xpcomPath;
return sXPCOMPath;
}
void
nsGREDirServiceProvider::AddGRELocationToPath()
{
char* grePath = GetGREDirectoryPath();
if (!grePath)
return;
const char* path = PR_GetEnv(XPCOM_SEARCH_KEY);
if (!path) {
path = "";
}
if (mPathEnvString)
PR_smprintf_free(mPathEnvString);
mPathEnvString = PR_smprintf("%s=%s;%s",
XPCOM_SEARCH_KEY,
grePath,
path);
#if XP_WIN32
// On windows, the current directory is searched before the
// PATH environment variable. This is a very bad thing
// since libraries in the cwd will be picked up before
// any that are in either the application or GRE directory.
char* cpd = GetGREDirectoryPath();
if (cpd) {
SetCurrentDirectory(cpd);
free (cpd);
}
#endif
PR_SetEnv(mPathEnvString);
free(grePath);
}

View File

@ -38,37 +38,31 @@
#ifndef nsGREDirServiceProvider_h_
#define nsGREDirServiceProvider_h_
#include "nsILocalFile.h"
#ifndef MAXPATHLEN
#ifdef _MAX_PATH
#define MAXPATHLEN _MAX_PATH
#elif defined(CCHMAXPATH)
#define MAXPATHLEN CCHMAXPATH
#else
#define MAXPATHLEN 1024
#endif
#endif
#include "nsIDirectoryService.h"
#include "nsDirectoryServiceDefs.h"
class nsIFile;
//*****************************************************************************
// class greEmbedFileLocProvider
//*****************************************************************************
/**
* the directoryserviceprovider used by GRE_Startup when calling NS_InitXPCOM2
*/
class nsGREDirServiceProvider : public nsIDirectoryServiceProvider
{
public:
nsGREDirServiceProvider();
nsGREDirServiceProvider() { }
NS_DECL_ISUPPORTS
NS_DECL_NSIDIRECTORYSERVICEPROVIDER
static char* GetXPCOMPath();
static char* GetGREDirectoryPath();
static char* GetPathFromConfigDir(const char* dirname);
static char* GetPathFromConfigFile(const char* filename);
protected:
virtual ~nsGREDirServiceProvider();
nsresult GetGreDirectory(nsILocalFile **aLocalFile);
void AddGRELocationToPath();
char* mPathEnvString;
virtual ~nsGREDirServiceProvider() { }
};
#endif // nsGREDirServiceProvider.h

View File

@ -35,24 +35,32 @@
*
* ***** END LICENSE BLOCK ***** */
#include "nspr.h"
#include "prlink.h"
#include "nsMemory.h"
#include "nsXPCOMPrivate.h"
#include "nsXPCOMGlue.h"
#include "nspr.h"
#include "nsMemory.h"
#include "nsGREDirServiceProvider.h"
#include "nsXPCOMPrivate.h"
#include <stdlib.h>
#if XP_WIN32
#include <windows.h>
#endif
void GRE_AddGREToEnvironment();
// functions provided by nsMemory.cpp and nsDebug.cpp
nsresult GlueStartupMemory();
void GlueShutdownMemory();
nsresult GlueStartupDebug();
void GlueShutdownDebug();
static PRLibrary *xpcomLib = nsnull;
static XPCOMFunctions *xpcomFunctions = nsnull;
static nsIMemory* xpcomMemory = nsnull;
extern nsresult GlueStartupMemory();
extern void GlueShutdownMemory();
extern nsresult GlueStartupDebug();
extern void GlueShutdownDebug();
extern "C"
nsresult NS_COM XPCOMGlueStartup(const char* xpcomFile)
nsresult XPCOMGlueStartup(const char* xpcomFile)
{
#ifdef XPCOM_GLUE_NO_DYNAMIC_LOADING
return NS_OK;
@ -121,12 +129,14 @@ nsresult NS_COM XPCOMGlueStartup(const char* xpcomFile)
return NS_ERROR_FAILURE;
}
GRE_AddGREToEnvironment();
return rv;
#endif
}
extern "C"
nsresult NS_COM XPCOMGlueShutdown()
nsresult XPCOMGlueShutdown()
{
#ifdef XPCOM_GLUE_NO_DYNAMIC_LOADING
return NS_OK;
@ -252,19 +262,66 @@ NS_GetTraceRefcnt(nsITraceRefcnt* *result)
#endif // #ifndef XPCOM_GLUE_NO_DYNAMIC_LOADING
static char sEnvString[MAXPATHLEN*10];
static char* spEnvString = 0;
void
GRE_AddGREToEnvironment()
{
const char* grePath = GRE_GetGREPath();
if (!grePath)
return;
const char* path = PR_GetEnv(XPCOM_SEARCH_KEY);
if (!path) {
path = "";
}
if (spEnvString) PR_smprintf_free(spEnvString);
/**
* if the PATH string is longer than our static buffer, allocate a
* buffer for the environment string. This buffer will be leaked at shutdown!
*/
if (strlen(grePath) + strlen(path) +
sizeof(XPCOM_SEARCH_KEY) + sizeof(XPCOM_ENV_PATH_SEPARATOR) > MAXPATHLEN*10) {
if (PR_smprintf(XPCOM_SEARCH_KEY "=%s" XPCOM_ENV_PATH_SEPARATOR "%s",
grePath,
path)) {
PR_SetEnv(spEnvString);
}
} else {
if (sprintf(sEnvString,
XPCOM_SEARCH_KEY "=%s" XPCOM_ENV_PATH_SEPARATOR "%s",
grePath,
path) > 0) {
PR_SetEnv(sEnvString);
}
}
#if XP_WIN32
// On windows, the current directory is searched before the
// PATH environment variable. This is a very bad thing
// since libraries in the cwd will be picked up before
// any that are in either the application or GRE directory.
if (grePath) {
SetCurrentDirectory(grePath);
}
#endif
}
// Default GRE startup/shutdown code
extern "C"
nsresult NS_COM GRE_Startup()
nsresult GRE_Startup()
{
char* xpcomLocation = nsGREDirServiceProvider::GetXPCOMPath();
const char* xpcomLocation = GRE_GetXPCOMPath();
// Startup the XPCOM Glue that links us up with XPCOM.
nsresult rv = XPCOMGlueStartup(xpcomLocation);
if (xpcomLocation)
free(xpcomLocation);
if (NS_FAILED(rv)) {
NS_WARNING("gre: XPCOMGlueStartup failed");
return rv;
@ -292,7 +349,7 @@ nsresult NS_COM GRE_Startup()
}
extern "C"
nsresult NS_COM GRE_Shutdown()
nsresult GRE_Shutdown()
{
NS_ShutdownXPCOM(nsnull);
XPCOMGlueShutdown();

View File

@ -39,17 +39,71 @@
class nsILocalFile;
extern "C"
nsresult NS_COM XPCOMGlueStartup(const char* xpcomFile);
/**
* Initialize the XPCOM glue by dynamically linking against the XPCOM
* shared library indicated by xpcomFile.
*/
extern "C"
nsresult NS_COM XPCOMGlueShutdown();
nsresult XPCOMGlueStartup(const char* xpcomFile);
// Default GRE startup and shutdown
/**
* Finish the XPCOM glue after it is no longer needed.
*/
extern "C"
nsresult NS_COM GRE_Startup();
nsresult XPCOMGlueShutdown();
/**
* Locate the path of a compatible GRE.
*
* @return string buffer pointing to the GRE path (without a trailing
* directory separator). Callers do no need to free this buffer.
*/
extern "C"
nsresult NS_COM GRE_Shutdown();
char const * GRE_GetGREPath();
/**
* Locate the path of a compatible GRE. This is returned as an
* nsILocalFile instead of a char*.
*
* @param _retval Ordinary XPCOM getter, returns an addrefed interface.
*/
extern "C"
nsresult GRE_GetGREDirectory(nsILocalFile* *_retval);
/**
* Locate the path of the XPCOM binary of a compatible GRE.
* The result of this function is normally passed directly to
* XPCOMGlueStartup.
*
* @return string buffer pointing to the XPCOM DLL path. Callers do
* not need to free this buffer.
*/
extern "C"
char const * GRE_GetXPCOMPath();
/**
* Embedding applications which don't need a custom
* directoryserviceprovider may use GRE_Startup to start the XPCOM
* glue and initialize the GRE in one step.
*/
extern "C"
nsresult GRE_Startup();
/**
* Shut down XPCOM and the XPCOM glue in one step.
*/
extern "C"
nsresult GRE_Shutdown();