diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 16:49:04 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 16:49:04 +0000 |
commit | 16f504a9dca3fe3b70568f67b7d41241ae485288 (patch) | |
tree | c60f36ada0496ba928b7161059ba5ab1ab224f9d /src/libs/xpcom18a4/xpcom/glue/standalone | |
parent | Initial commit. (diff) | |
download | virtualbox-16f504a9dca3fe3b70568f67b7d41241ae485288.tar.xz virtualbox-16f504a9dca3fe3b70568f67b7d41241ae485288.zip |
Adding upstream version 7.0.6-dfsg.upstream/7.0.6-dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/libs/xpcom18a4/xpcom/glue/standalone')
6 files changed, 1393 insertions, 0 deletions
diff --git a/src/libs/xpcom18a4/xpcom/glue/standalone/.cvsignore b/src/libs/xpcom18a4/xpcom/glue/standalone/.cvsignore new file mode 100644 index 00000000..a0182c1f --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/glue/standalone/.cvsignore @@ -0,0 +1,8 @@ +Makefile +nsCOMPtr.cpp +nsDebug.cpp +nsGenericFactory.cpp +nsIInterfaceRequestorUtils.cpp +nsMemory.cpp +nsWeakReference.cpp +nsComponentManagerUtils.cpp diff --git a/src/libs/xpcom18a4/xpcom/glue/standalone/Makefile.in b/src/libs/xpcom18a4/xpcom/glue/standalone/Makefile.in new file mode 100644 index 00000000..ae23d8e0 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/glue/standalone/Makefile.in @@ -0,0 +1,88 @@ +# ***** BEGIN LICENSE BLOCK ***** +# Version: MPL 1.1/GPL 2.0/LGPL 2.1 +# +# The contents of this file are subject to the Mozilla Public License Version +# 1.1 (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +# for the specific language governing rights and limitations under the +# License. +# +# The Original Code is mozilla.org. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2002 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# +# Alternatively, the contents of this file may be used under the terms of +# either the GNU General Public License Version 2 or later (the "GPL"), or +# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +# in which case the provisions of the GPL or the LGPL are applicable instead +# of those above. If you wish to allow use of your version of this file only +# under the terms of either the GPL or the LGPL, and not to allow others to +# use your version of this file under the terms of the MPL, indicate your +# decision by deleting the provisions above and replace them with the notice +# and other provisions required by the GPL or the LGPL. If you do not delete +# the provisions above, a recipient may use your version of this file under +# the terms of any one of the MPL, the GPL or the LGPL. +# +# ***** END LICENSE BLOCK ***** + +DEPTH = ../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk +include $(srcdir)/../objs.mk + +MODULE = xpcom +LIBRARY_NAME = xpcomglue + +REQUIRES = string \ + $(NULL) + +LOCAL_INCLUDES = \ + -I$(srcdir)/../../build \ + $(NULL) + +CPPSRCS = \ + $(XPCOM_GLUE_SRC_LCSRCS) \ + nsXPCOMGlue.cpp \ + nsGREDirServiceProvider.cpp \ + $(NULL) + +SDK_HEADERS = \ + nsXPCOMGlue.h \ + $(NULL) + +SDK_LIBRARY = \ + $(LIB_PREFIX)xpcomglue.$(LIB_SUFFIX) \ + $(NULL) + +# we don't want the shared lib, but we want to force the creation of a static lib. +FORCE_STATIC_LIB = 1 + +# Force use of PIC +FORCE_USE_PIC = 1 + +GARBAGE += $(XPCOM_GLUE_SRC_LCSRCS) $(wildcard *.$(OBJ_SUFFIX)) + +ifeq ($(OS_ARCH),WINNT) +GARBAGE += $(addprefix $(srcdir)/,$(XPCOM_GLUE_SRC_LCSRCS)) +endif + +SRCS_IN_OBJDIR = 1 + +include $(topsrcdir)/config/rules.mk + +export:: $(XPCOM_GLUE_SRC_CSRCS) + $(INSTALL) $^ . + +DEFINES += -DXPCOM_GLUE diff --git a/src/libs/xpcom18a4/xpcom/glue/standalone/nsGREDirServiceProvider.cpp b/src/libs/xpcom18a4/xpcom/glue/standalone/nsGREDirServiceProvider.cpp new file mode 100644 index 00000000..4a1247eb --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/glue/standalone/nsGREDirServiceProvider.cpp @@ -0,0 +1,596 @@ +/* -*- 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 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corp. + * Portions created by the Initial Developer are Copyright (C) 2003 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Sean Su <ssu@netscape.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsBuildID.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 "plstr.h" + +#ifdef XP_WIN32 +#include <windows.h> +#include <stdlib.h> +#elif defined(XP_OS2) +#define INCL_DOS +#include <os2.h> +#include <stdlib.h> +#include <stdio.h> +#include "prenv.h" +#elif defined(XP_MACOSX) +#include <Processes.h> +#include <CFBundle.h> +#elif defined(XP_UNIX) +#include <unistd.h> +#include <stdlib.h> +#include <sys/param.h> +#include <dlfcn.h> +#include "prenv.h" +#elif defined(XP_BEOS) +#include <FindDirectory.h> +#include <Path.h> +#include <unistd.h> +#include <stdlib.h> +#include <sys/param.h> +#include <OS.h> +#include <image.h> +#include "prenv.h" +#endif + +#include <sys/stat.h> + +#include "nsGREDirServiceProvider.h" + +PRBool GRE_GetCurrentProcessDirectory(char* buffer); +PRBool GRE_GetPathFromConfigDir(const char* dirname, char* buffer); +PRBool GRE_GetPathFromConfigFile(const char* dirname, char* buffer); + +//***************************************************************************** +// nsGREDirServiceProvider::nsISupports +//***************************************************************************** + +NS_IMPL_ISUPPORTS1(nsGREDirServiceProvider, nsIDirectoryServiceProvider) + +//***************************************************************************** +// nsGREDirServiceProvider::nsIDirectoryServiceProvider +//***************************************************************************** + +NS_IMETHODIMP +nsGREDirServiceProvider::GetFile(const char *prop, PRBool *persistant, nsIFile **_retval) +{ + *_retval = nsnull; + *persistant = PR_TRUE; + + //--------------------------------------------------------------- + // Note that by returning a valid localFile's for NS_GRE_DIR, + // your app is indicating to XPCOM that it found a GRE version + // with which it's compatible with and intends to be "run against" + // that GRE. + // + // Please see http://www.mozilla.org/projects/embedding/GRE.html + // for more info on GRE. + //--------------------------------------------------------------- + if(strcmp(prop, NS_GRE_DIR) == 0) + { + nsILocalFile* lfile = nsnull; + nsresult rv = GRE_GetGREDirectory(&lfile); + *_retval = lfile; + return rv; + } + + return NS_ERROR_FAILURE; +} + +//***************************************************************************** +// Implementations from nsXPCOMGlue.h and helper functions. +//***************************************************************************** + +PRBool +GRE_GetCurrentProcessDirectory(char* buffer) +{ + *buffer = '\0'; + +#ifdef XP_WIN + if ( ::GetModuleFileName(0, buffer, MAXPATHLEN) ) { + // chop of the executable name by finding the rightmost backslash + char* lastSlash = PL_strrchr(buffer, '\\'); + if (lastSlash) { + *(lastSlash) = '\0'; + return PR_TRUE; + } + } + +#elif defined(XP_MACOSX) + // Works even if we're not bundled. + CFBundleRef appBundle = CFBundleGetMainBundle(); + if (appBundle != nsnull) + { + CFURLRef bundleURL = CFBundleCopyExecutableURL(appBundle); + if (bundleURL != nsnull) + { + CFURLRef parentURL = CFURLCreateCopyDeletingLastPathComponent(kCFAllocatorDefault, bundleURL); + if (parentURL) + { + CFStringRef path = CFURLCopyFileSystemPath(parentURL, kCFURLPOSIXPathStyle); + if (path) + { + CFStringGetCString(path, buffer, MAXPATHLEN, kCFStringEncodingUTF8); + CFRelease(path); + } + CFRelease(parentURL); + } + CFRelease(bundleURL); + } +#if 0 /* bird: Causes crashes in objc_msgSend() later if released. I dunno why really. + Something could be seriously screwed up somewhere else, but this'll have + to do for now. (appBundle isn't released in the other place it's used.) */ + CFRelease(appBundle); +#endif + } + if (*buffer) return PR_TRUE; + +#elif defined(XP_UNIX) + +#if 0 /* we need .so location. */ + // Actually we have a way on linux. + static volatile bool fPathSet = false; + static char szPath[MAXPATHLEN]; + if (!fPathSet) + { + char buf2[MAXPATHLEN + 3]; + buf2[0] = '\0'; + + /* + * Env.var. VBOX_XPCOM_HOME first. + */ + char *psz = PR_GetEnv("VBOX_XPCOM_HOME"); + if (psz) + { + if (strlen(psz) < MAXPATHLEN) + { + if (!realpath(psz, buf2)) + strcpy(buf2, psz); + strcat(buf2, "/x"); /* for the filename stripping */ + } + } + + /* + * The dynamic loader. + */ + if (!buf2[0]) + { + Dl_info DlInfo = {0}; + if ( !dladdr((const void *)GRE_GetCurrentProcessDirectory, &DlInfo) + && DlInfo.dli_fname) + { + if (!realpath(DlInfo.dli_fname, buf2)) + buf2[0] = '\0'; + } + } + + /* + * Executable location. + */ + if (!buf2[0]) + { + char buf[MAXPATHLEN]; + int cchLink = readlink("/proc/self/exe", buf, sizeof(buf) - 1); + if (cchLink > 0 || cchLink != sizeof(buf) - 1) + { + buf[cchLink] = '\0'; + if (!realpath(buf, buf2)) + buf2[0] = '\0'; + } + } + + /* + * Copy to static buffer on success. + */ + if (buf2[0]) + { + char *p = strrchr(buf2, '/'); + if (p) + { + p[p == buf2] = '\0'; + #ifdef DEBUG + printf("debug: (1) VBOX_XPCOM_HOME=%s\n", buf2); + #endif + strcpy(szPath, buf2); + fPathSet = true; + } + } + } + if (fPathSet) + { + strcpy(buffer, szPath); + return PR_TRUE; + } +#endif + + // In the absence of a good way to get the executable directory let + // us try this for unix: + // - if VBOX_XPCOM_HOME is defined, that is it + // - else give the current directory + + // The MOZ_DEFAULT_VBOX_XPCOM_HOME variable can be set at configure time with + // a --with-default-mozilla-five-home=foo autoconf flag. + // + // The idea here is to allow for builds that have a default VBOX_XPCOM_HOME + // regardless of the environment. This makes it easier to write apps that + // embed mozilla without having to worry about setting up the environment + // + // We do this py putenv()ing the default value into the environment. Note that + // we only do this if it is not already set. +#ifdef MOZ_DEFAULT_VBOX_XPCOM_HOME + if (PR_GetEnv("VBOX_XPCOM_HOME") == nsnull) + { + putenv("VBOX_XPCOM_HOME=" MOZ_DEFAULT_VBOX_XPCOM_HOME); + } +#endif + + char *moz5 = PR_GetEnv("VBOX_XPCOM_HOME"); + + if (moz5 && *moz5) + { + if (!realpath(moz5, buffer)) + strcpy(buffer, moz5); + + return PR_TRUE; + } + else + { +#if defined(DEBUG) + static PRBool firstWarning = PR_TRUE; + + if(firstWarning) { + // Warn that VBOX_XPCOM_HOME not set, once. + printf("Warning: VBOX_XPCOM_HOME not set.\n"); + firstWarning = PR_FALSE; + } +#endif /* DEBUG */ + + // Fall back to current directory. + if (getcwd(buffer, MAXPATHLEN)) + { + return PR_TRUE; + } + } + +#elif defined(XP_OS2) + PPIB ppib; + PTIB ptib; + char* p; + DosGetInfoBlocks( &ptib, &ppib); + DosQueryModuleName( ppib->pib_hmte, MAXPATHLEN, buffer); + p = strrchr( buffer, '\\'); // XXX DBCS misery + if (p) { + *p = '\0'; + return PR_TRUE; + } + +#elif defined(XP_BEOS) + + char *moz5 = getenv("VBOX_XPCOM_HOME"); + if (moz5) + { + strcpy(buffer, moz5); + return PR_TRUE; + } + else + { + int32 cookie = 0; + image_info info; + char *p; + *buffer = 0; + if(get_next_image_info(0, &cookie, &info) == B_OK) + { + strcpy(buffer, info.name); + if((p = strrchr(buffer, '/')) != 0) + { + *p = 0; + + return PR_TRUE; + } + } + } + +#endif + + return PR_FALSE; +} + +/** + * the GRE location is stored in a static buffer so that we don't have + * to compute it multiple times. + */ + +static char sGRELocation[MAXPATHLEN] = ""; + +extern "C" char const * +GRE_GetGREPath() +{ + // we've already done this... + if (*sGRELocation) + return sGRELocation; + + 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 + buffer[pathlen] = '\0'; + strcpy(sGRELocation, buffer); + return sGRELocation; + } + } + + // 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 + env = PR_GetEnv("USE_LOCAL_GRE"); + if (env && *env) + return nsnull; + +#if XP_UNIX + // check in the HOME directory + env = PR_GetEnv("HOME"); + if (env && *env) { +# ifdef VBOX + snprintf(buffer, sizeof(buffer), "%s" XPCOM_FILE_PATH_SEPARATOR GRE_CONF_NAME, env); +# else + sprintf(buffer, "%s" XPCOM_FILE_PATH_SEPARATOR GRE_CONF_NAME, env); +# endif + + if (GRE_GetPathFromConfigFile(buffer, sGRELocation)) { + return sGRELocation; + } + } +#endif + + env = PR_GetEnv("MOZ_GRE_CONF"); + if (env) { + if (GRE_GetPathFromConfigFile(env, sGRELocation)) { + return sGRELocation; + } + } + +#if XP_UNIX + // Look for a group of config files in /etc/gre.d/ + if (GRE_GetPathFromConfigDir(GRE_CONF_DIR, sGRELocation)) { + return sGRELocation; + } + + // Look for a global /etc/gre.conf file + if (GRE_GetPathFromConfigFile(GRE_CONF_PATH, sGRELocation)) { + return sGRELocation; + } +#endif + +#if XP_WIN32 + char szKey[256]; + HKEY hRegKey = NULL; + 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 + // 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/GRE.html for + // more info. + // + strcpy(szKey, GRE_WIN_REG_LOC GRE_BUILD_ID); + + 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; + } +#endif + + return nsnull; +} + +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 + // point to the GRE that we're interested in. + PRDir *dir = PR_OpenDir(dirname); + if (!dir) + return nsnull; + + PRBool found = PR_FALSE; + PRDirEntry *entry; + + while (!found && (entry = PR_ReadDir(dir, PR_SKIP_BOTH))) { + + // Only look for files that end in .conf + char *offset = PL_strrstr(entry->name, ".conf"); + if (!offset) + continue; + + if (offset != entry->name + strlen(entry->name) - 5) + continue; + + nsEmbedCString fullPath; + NS_CStringAppendData(fullPath, dirname); + NS_CStringAppendData(fullPath, XPCOM_FILE_PATH_SEPARATOR); + NS_CStringAppendData(fullPath, entry->name); + + found = GRE_GetPathFromConfigFile(fullPath.get(), buffer); + } + + PR_CloseDir(dir); + + return found; +} + +PRBool +GRE_GetPathFromConfigFile(const char* filename, char* pathBuffer) +{ + *pathBuffer = '\0'; + char buffer[1024]; + FILE *cfg; + PRBool foundHeader = PR_FALSE; + PRInt32 versionLen = sizeof(GRE_BUILD_ID)-1; + + if((cfg=fopen(filename,"r"))==nsnull) { + return nsnull; + } + + while (fgets(buffer, 1024, cfg) != nsnull) { + // skip over comment lines and blank lines + 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, GRE_BUILD_ID, versionLen)) { + foundHeader = PR_TRUE; + } + continue; + } + + if (foundHeader && !strncmp (buffer, "GRE_PATH=", 9)) { + strcpy(pathBuffer, buffer + 9); + // kill the line feed if any + PRInt32 len = strlen(pathBuffer); + len--; + + if (pathBuffer[len] == '\n') + pathBuffer[len] = '\0'; + break; + } + } + fclose(cfg); + return (*pathBuffer != '\0'); +} + +extern "C" nsresult +GRE_GetGREDirectory(nsILocalFile* *_retval) +{ + 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 + + const char *pGREDir = GRE_GetGREPath(); + if(pGREDir) { + nsCOMPtr<nsILocalFile> tempLocal; + nsEmbedCString leaf; + NS_CStringSetData(leaf, pGREDir); + rv = NS_NewNativeLocalFile(leaf, PR_TRUE, getter_AddRefs(tempLocal)); + + if (NS_SUCCEEDED(rv)) { + *_retval = tempLocal; + NS_ADDREF(*_retval); + } + } + return rv; +} + +static char sXPCOMPath[MAXPATHLEN]; + +extern "C" const char* +GRE_GetXPCOMPath() +{ + const char* grePath = GRE_GetGREPath(); + + if (!grePath) { + grePath = PR_GetEnv("VBOX_XPCOM_HOME"); + if (!grePath || !*grePath) { + return nsnull; + } + } + +#ifdef VBOX + snprintf(sXPCOMPath, sizeof(sXPCOMPath), "%s" XPCOM_FILE_PATH_SEPARATOR XPCOM_DLL, grePath); +#else + sprintf(sXPCOMPath, "%s" XPCOM_FILE_PATH_SEPARATOR XPCOM_DLL, grePath); +#endif + + return sXPCOMPath; +} diff --git a/src/libs/xpcom18a4/xpcom/glue/standalone/nsGREDirServiceProvider.h b/src/libs/xpcom18a4/xpcom/glue/standalone/nsGREDirServiceProvider.h new file mode 100644 index 00000000..0638a127 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/glue/standalone/nsGREDirServiceProvider.h @@ -0,0 +1,68 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corp. + * Portions created by the Initial Developer are Copyright (C) 2003 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Sean Su <ssu@netscape.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef nsGREDirServiceProvider_h_ +#define nsGREDirServiceProvider_h_ + +#include "nsIDirectoryService.h" + +#ifndef MAXPATHLEN +#ifdef _MAX_PATH +#define MAXPATHLEN _MAX_PATH +#elif defined(CCHMAXPATH) +#define MAXPATHLEN CCHMAXPATH +#else +#define MAXPATHLEN 1024 +#endif +#endif + +/** + * the directoryserviceprovider used by GRE_Startup when calling NS_InitXPCOM2 + */ +class nsGREDirServiceProvider : public nsIDirectoryServiceProvider +{ +public: + nsGREDirServiceProvider() { } + + NS_DECL_ISUPPORTS + NS_DECL_NSIDIRECTORYSERVICEPROVIDER + +private: + ~nsGREDirServiceProvider() { } +}; + +#endif // nsGREDirServiceProvider.h diff --git a/src/libs/xpcom18a4/xpcom/glue/standalone/nsXPCOMGlue.cpp b/src/libs/xpcom18a4/xpcom/glue/standalone/nsXPCOMGlue.cpp new file mode 100644 index 00000000..091538fa --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/glue/standalone/nsXPCOMGlue.cpp @@ -0,0 +1,524 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* vim:set ts=4 sw=4 et cindent: */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsXPCOMGlue.h" + +#include "nspr.h" +#include "nsMemory.h" +#include "nsGREDirServiceProvider.h" +#include "nsXPCOMPrivate.h" +#include <stdlib.h> +#ifdef VBOX +# include <limits.h> +#endif + +#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; +static XPCOMFunctions xpcomFunctions; + +extern "C" +nsresult XPCOMGlueStartup(const char* xpcomFile) +{ +#ifdef XPCOM_GLUE_NO_DYNAMIC_LOADING + return NS_OK; +#else + nsresult rv = NS_OK; + GetFrozenFunctionsFunc function = nsnull; + + xpcomFunctions.version = XPCOM_GLUE_VERSION; + xpcomFunctions.size = sizeof(XPCOMFunctions); + + // + // if xpcomFile == ".", then we assume xpcom is already loaded, and we'll + // use NSPR to find NS_GetFrozenFunctions from the list of already loaded + // libraries. + // + // otherwise, we try to load xpcom and then look for NS_GetFrozenFunctions. + // if xpcomFile == NULL, then we try to load xpcom by name w/o a fully + // qualified path. + // + + if (xpcomFile && (xpcomFile[0] == '.' && xpcomFile[1] == '\0')) { + function = (GetFrozenFunctionsFunc) + PR_FindSymbolAndLibrary("NS_GetFrozenFunctions", &xpcomLib); + if (!function) { + // The symbol was not found, so failover to loading XPCOM_DLL, + // and look for the symbol there. See bug 240986 for details. + xpcomFile = nsnull; + } + else { + char *libPath = PR_GetLibraryFilePathname(XPCOM_DLL, (PRFuncPtr) function); + if (!libPath) + rv = NS_ERROR_FAILURE; + else { + rv = (*function)(&xpcomFunctions, libPath); + PR_Free(libPath); + } + } + } + + if (!function) { + PRLibSpec libSpec; + + libSpec.type = PR_LibSpec_Pathname; + if (!xpcomFile) + libSpec.value.pathname = XPCOM_DLL; + else + libSpec.value.pathname = xpcomFile; + + xpcomLib = PR_LoadLibraryWithFlags(libSpec, PR_LD_LAZY|PR_LD_GLOBAL); +#ifdef RT_OS_DARWIN /* vbox */ + /* works around bundle problem. */ + if (!xpcomLib) { + const char *home = PR_GetEnv("VBOX_XPCOM_HOME"); + if (home) { + char path[PATH_MAX]; + snprintf(path, sizeof(path), "%s/%s", home, libSpec.value.pathname); + libSpec.value.pathname = path; + xpcomLib = PR_LoadLibraryWithFlags(libSpec, PR_LD_LAZY|PR_LD_GLOBAL); + } + } +#endif + if (!xpcomLib) + return NS_ERROR_FAILURE; + + function = (GetFrozenFunctionsFunc) PR_FindSymbol(xpcomLib, "NS_GetFrozenFunctions"); + + if (!function) + rv = NS_ERROR_FAILURE; + else + rv = (*function)(&xpcomFunctions, libSpec.value.pathname); + } + + if (NS_FAILED(rv)) + goto bail; + + rv = GlueStartupDebug(); + if (NS_FAILED(rv)) + goto bail; + + // startup the nsMemory + rv = GlueStartupMemory(); + if (NS_FAILED(rv)) { + GlueShutdownDebug(); + goto bail; + } + + GRE_AddGREToEnvironment(); + return NS_OK; + +bail: + PR_UnloadLibrary(xpcomLib); + xpcomLib = nsnull; + memset(&xpcomFunctions, 0, sizeof(xpcomFunctions)); + return NS_ERROR_FAILURE; +#endif +} + +extern "C" +nsresult XPCOMGlueShutdown() +{ +#ifdef XPCOM_GLUE_NO_DYNAMIC_LOADING + return NS_OK; +#else + + GlueShutdownMemory(); + + GlueShutdownDebug(); + + if (xpcomLib) { + PR_UnloadLibrary(xpcomLib); + xpcomLib = nsnull; + } + + memset(&xpcomFunctions, 0, sizeof(xpcomFunctions)); + return NS_OK; +#endif +} + +#ifndef XPCOM_GLUE_NO_DYNAMIC_LOADING +extern "C" NS_COM nsresult +NS_InitXPCOM2(nsIServiceManager* *result, + nsIFile* binDirectory, + nsIDirectoryServiceProvider* appFileLocationProvider) +{ + if (!xpcomFunctions.init) + return NS_ERROR_NOT_INITIALIZED; + return xpcomFunctions.init(result, binDirectory, appFileLocationProvider); +} + +extern "C" NS_COM nsresult +NS_ShutdownXPCOM(nsIServiceManager* servMgr) +{ + if (!xpcomFunctions.shutdown) + return NS_ERROR_NOT_INITIALIZED; + return xpcomFunctions.shutdown(servMgr); +} + +extern "C" NS_COM nsresult +NS_GetServiceManager(nsIServiceManager* *result) +{ + if (!xpcomFunctions.getServiceManager) + return NS_ERROR_NOT_INITIALIZED; + return xpcomFunctions.getServiceManager(result); +} + +extern "C" NS_COM nsresult +NS_GetComponentManager(nsIComponentManager* *result) +{ + if (!xpcomFunctions.getComponentManager) + return NS_ERROR_NOT_INITIALIZED; + return xpcomFunctions.getComponentManager(result); +} + +extern "C" NS_COM nsresult +NS_GetComponentRegistrar(nsIComponentRegistrar* *result) +{ + if (!xpcomFunctions.getComponentRegistrar) + return NS_ERROR_NOT_INITIALIZED; + return xpcomFunctions.getComponentRegistrar(result); +} + +extern "C" NS_COM nsresult +NS_GetMemoryManager(nsIMemory* *result) +{ + if (!xpcomFunctions.getMemoryManager) + return NS_ERROR_NOT_INITIALIZED; + return xpcomFunctions.getMemoryManager(result); +} + +extern "C" NS_COM nsresult +NS_NewLocalFile(const nsAString &path, PRBool followLinks, nsILocalFile* *result) +{ + if (!xpcomFunctions.newLocalFile) + return NS_ERROR_NOT_INITIALIZED; + return xpcomFunctions.newLocalFile(path, followLinks, result); +} + +extern "C" NS_COM nsresult +NS_NewNativeLocalFile(const nsACString &path, PRBool followLinks, nsILocalFile* *result) +{ + if (!xpcomFunctions.newNativeLocalFile) + return NS_ERROR_NOT_INITIALIZED; + return xpcomFunctions.newNativeLocalFile(path, followLinks, result); +} + +extern "C" NS_COM nsresult +NS_RegisterXPCOMExitRoutine(XPCOMExitRoutine exitRoutine, PRUint32 priority) +{ + if (!xpcomFunctions.registerExitRoutine) + return NS_ERROR_NOT_INITIALIZED; + return xpcomFunctions.registerExitRoutine(exitRoutine, priority); +} + +extern "C" NS_COM nsresult +NS_UnregisterXPCOMExitRoutine(XPCOMExitRoutine exitRoutine) +{ + if (!xpcomFunctions.unregisterExitRoutine) + return NS_ERROR_NOT_INITIALIZED; + return xpcomFunctions.unregisterExitRoutine(exitRoutine); +} + +extern "C" NS_COM nsresult +NS_GetDebug(nsIDebug* *result) +{ + if (!xpcomFunctions.getDebug) + return NS_ERROR_NOT_INITIALIZED; + return xpcomFunctions.getDebug(result); +} + + +extern "C" NS_COM nsresult +NS_GetTraceRefcnt(nsITraceRefcnt* *result) +{ + if (!xpcomFunctions.getTraceRefcnt) + return NS_ERROR_NOT_INITIALIZED; + return xpcomFunctions.getTraceRefcnt(result); +} + + +extern "C" NS_COM nsresult +NS_StringContainerInit(nsStringContainer &aStr) +{ + if (!xpcomFunctions.stringContainerInit) + return NS_ERROR_NOT_INITIALIZED; + return xpcomFunctions.stringContainerInit(aStr); +} + +extern "C" NS_COM void +NS_StringContainerFinish(nsStringContainer &aStr) +{ + if (xpcomFunctions.stringContainerFinish) + xpcomFunctions.stringContainerFinish(aStr); +} + +extern "C" NS_COM PRUint32 +NS_StringGetData(const nsAString &aStr, const PRUnichar **aBuf, PRBool *aTerm) +{ + if (!xpcomFunctions.stringGetData) { + *aBuf = nsnull; + return 0; + } + return xpcomFunctions.stringGetData(aStr, aBuf, aTerm); +} + +extern "C" NS_COM PRUnichar * +NS_StringCloneData(const nsAString &aStr) +{ + if (!xpcomFunctions.stringCloneData) + return nsnull; + return xpcomFunctions.stringCloneData(aStr); +} + +extern "C" NS_COM nsresult +NS_StringSetData(nsAString &aStr, const PRUnichar *aBuf, PRUint32 aCount) +{ + if (!xpcomFunctions.stringSetData) + return NS_ERROR_NOT_INITIALIZED; + + return xpcomFunctions.stringSetData(aStr, aBuf, aCount); +} + +extern "C" NS_COM nsresult +NS_StringSetDataRange(nsAString &aStr, PRUint32 aCutStart, PRUint32 aCutLength, + const PRUnichar *aBuf, PRUint32 aCount) +{ + if (!xpcomFunctions.stringSetDataRange) + return NS_ERROR_NOT_INITIALIZED; + return xpcomFunctions.stringSetDataRange(aStr, aCutStart, aCutLength, aBuf, aCount); +} + +extern "C" NS_COM nsresult +NS_StringCopy(nsAString &aDest, const nsAString &aSrc) +{ + if (!xpcomFunctions.stringCopy) + return NS_ERROR_NOT_INITIALIZED; + return xpcomFunctions.stringCopy(aDest, aSrc); +} + + +extern "C" NS_COM nsresult +NS_CStringContainerInit(nsCStringContainer &aStr) +{ + if (!xpcomFunctions.cstringContainerInit) + return NS_ERROR_NOT_INITIALIZED; + return xpcomFunctions.cstringContainerInit(aStr); +} + +extern "C" NS_COM void +NS_CStringContainerFinish(nsCStringContainer &aStr) +{ + if (xpcomFunctions.cstringContainerFinish) + xpcomFunctions.cstringContainerFinish(aStr); +} + +extern "C" NS_COM PRUint32 +NS_CStringGetData(const nsACString &aStr, const char **aBuf, PRBool *aTerm) +{ + if (!xpcomFunctions.cstringGetData) { + *aBuf = nsnull; + return 0; + } + return xpcomFunctions.cstringGetData(aStr, aBuf, aTerm); +} + +extern "C" NS_COM char * +NS_CStringCloneData(const nsACString &aStr) +{ + if (!xpcomFunctions.cstringCloneData) + return nsnull; + return xpcomFunctions.cstringCloneData(aStr); +} + +extern "C" NS_COM nsresult +NS_CStringSetData(nsACString &aStr, const char *aBuf, PRUint32 aCount) +{ + if (!xpcomFunctions.cstringSetData) + return NS_ERROR_NOT_INITIALIZED; + return xpcomFunctions.cstringSetData(aStr, aBuf, aCount); +} + +extern "C" NS_COM nsresult +NS_CStringSetDataRange(nsACString &aStr, PRUint32 aCutStart, PRUint32 aCutLength, + const char *aBuf, PRUint32 aCount) +{ + if (!xpcomFunctions.cstringSetDataRange) + return NS_ERROR_NOT_INITIALIZED; + return xpcomFunctions.cstringSetDataRange(aStr, aCutStart, aCutLength, aBuf, aCount); +} + +extern "C" NS_COM nsresult +NS_CStringCopy(nsACString &aDest, const nsACString &aSrc) +{ + if (!xpcomFunctions.cstringCopy) + return NS_ERROR_NOT_INITIALIZED; + return xpcomFunctions.cstringCopy(aDest, aSrc); +} + +extern "C" NS_COM nsresult +NS_CStringToUTF16(const nsACString &aSrc, PRUint32 aSrcEncoding, nsAString &aDest) +{ + if (!xpcomFunctions.cstringToUTF16) + return NS_ERROR_NOT_INITIALIZED; + return xpcomFunctions.cstringToUTF16(aSrc, aSrcEncoding, aDest); +} + +extern "C" NS_COM nsresult +NS_UTF16ToCString(const nsAString &aSrc, PRUint32 aDestEncoding, nsACString &aDest) +{ + if (!xpcomFunctions.utf16ToCString) + return NS_ERROR_NOT_INITIALIZED; + return xpcomFunctions.utf16ToCString(aSrc, aDestEncoding, aDest); +} + +#endif // #ifndef XPCOM_GLUE_NO_DYNAMIC_LOADING + + +static char sEnvString[MAXPATHLEN*10]; +static char* spEnvString = 0; + +void +GRE_AddGREToEnvironment() +{ + const char* grePath = GRE_GetGREPath(); + char szPath[MAXPATHLEN]; + if (!grePath) + return; + + const char* path = PR_GetEnv(XPCOM_SEARCH_KEY); + if (!path) + path = ""; +#ifdef VBOX + else + { + /* sEnvString is part of the environment because of putenv(). + * path is only temporarily used and not argument of putenv() itself */ + snprintf(szPath, sizeof(szPath), "%s", path); + path = szPath; + } +#endif + + 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 GRE_Startup() +{ + const char* xpcomLocation = GRE_GetXPCOMPath(); + + // Startup the XPCOM Glue that links us up with XPCOM. + nsresult rv = XPCOMGlueStartup(xpcomLocation); + + if (NS_FAILED(rv)) { + NS_WARNING("gre: XPCOMGlueStartup failed"); + return rv; + } + + nsGREDirServiceProvider *provider = new nsGREDirServiceProvider(); + if ( !provider ) { + NS_WARNING("GRE_Startup failed"); + XPCOMGlueShutdown(); + return NS_ERROR_OUT_OF_MEMORY; + } + + nsCOMPtr<nsIServiceManager> servMan; + NS_ADDREF( provider ); + rv = NS_InitXPCOM2(getter_AddRefs(servMan), nsnull, provider); + NS_RELEASE(provider); + + if ( NS_FAILED(rv) || !servMan) { + NS_WARNING("gre: NS_InitXPCOM failed"); + XPCOMGlueShutdown(); + return rv; + } + + return NS_OK; +} + +extern "C" +nsresult GRE_Shutdown() +{ + NS_ShutdownXPCOM(nsnull); + XPCOMGlueShutdown(); + return NS_OK; +} diff --git a/src/libs/xpcom18a4/xpcom/glue/standalone/nsXPCOMGlue.h b/src/libs/xpcom18a4/xpcom/glue/standalone/nsXPCOMGlue.h new file mode 100644 index 00000000..6044e084 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/glue/standalone/nsXPCOMGlue.h @@ -0,0 +1,109 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nscore.h" + +class nsILocalFile; + +/** + * Initialize the XPCOM glue by dynamically linking against the XPCOM + * shared library indicated by xpcomFile. + */ + +extern "C" +nsresult XPCOMGlueStartup(const char* xpcomFile); + + +/** + * Finish the XPCOM glue after it is no longer needed. + */ + +extern "C" +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" +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(); |