summaryrefslogtreecommitdiffstats
path: root/xulrunner/stub
diff options
context:
space:
mode:
Diffstat (limited to 'xulrunner/stub')
-rw-r--r--xulrunner/stub/Makefile.in11
-rw-r--r--xulrunner/stub/moz.build51
-rw-r--r--xulrunner/stub/nsXULStub.cpp445
-rw-r--r--xulrunner/stub/xulrunner-stub.exe.manifest38
-rw-r--r--xulrunner/stub/xulrunner-stub.rc6
5 files changed, 551 insertions, 0 deletions
diff --git a/xulrunner/stub/Makefile.in b/xulrunner/stub/Makefile.in
new file mode 100644
index 000000000..0fa0cccf6
--- /dev/null
+++ b/xulrunner/stub/Makefile.in
@@ -0,0 +1,11 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+ifndef MOZ_WINCONSOLE
+ifdef MOZ_DEBUG
+MOZ_WINCONSOLE = 1
+else
+MOZ_WINCONSOLE = 0
+endif
+endif
diff --git a/xulrunner/stub/moz.build b/xulrunner/stub/moz.build
new file mode 100644
index 000000000..4fd172f72
--- /dev/null
+++ b/xulrunner/stub/moz.build
@@ -0,0 +1,51 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+# The value of XULRUNNER_STUB_NAME is generated by configure to allow XULRunner
+# apps to override it using the --with-xulrunner-stub-name=<appname> argument.
+# If this configure argument is not present then the default name is
+# 'xulrunner-stub'.
+
+# We don't want to create a dependency on mozglue.
+# Statically link against the RTL on windows
+GeckoProgram(CONFIG['XULRUNNER_STUB_NAME'], mozglue=None, msvcrt='static')
+
+SOURCES += [
+ 'nsXULStub.cpp',
+]
+
+if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
+ FINAL_TARGET = 'dist/XUL.framework/Versions/%(MOZILLA_VERSION)s' % CONFIG
+
+DEFINES['XPCOM_GLUE'] = True
+
+LOCAL_INCLUDES += [
+ '/xpcom/base',
+ '/xpcom/build',
+]
+
+if CONFIG['OS_ARCH'] == 'WINNT':
+ LOCAL_INCLUDES += ['/toolkit/xre']
+ # this is an awful workaround - glandium
+ USE_LIBS += ['mfbt_staticruntime']
+
+if CONFIG['_MSC_VER']:
+ WIN32_EXE_LDFLAGS += ['-ENTRY:wmainCRTStartup']
+
+if CONFIG['OS_ARCH'] == 'WINNT':
+ DEFINES['MOZ_XULRUNNER'] = True
+ RCINCLUDE = 'xulrunner-stub.rc'
+
+if CONFIG['OS_ARCH'] == 'WINNT':
+ OS_LIBS += [
+ 'shell32',
+ ]
+
+DISABLE_STL_WRAPPING = True
+
+# Need to link with CoreFoundation on Mac
+if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
+ OS_LIBS += CONFIG['TK_LIBS']
diff --git a/xulrunner/stub/nsXULStub.cpp b/xulrunner/stub/nsXULStub.cpp
new file mode 100644
index 000000000..8638ae43e
--- /dev/null
+++ b/xulrunner/stub/nsXULStub.cpp
@@ -0,0 +1,445 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsXPCOMGlue.h"
+#include "nsINIParser.h"
+#include "nsXPCOMPrivate.h" // for XP MAXPATHLEN
+#include "nsXULAppAPI.h"
+#include "nsIFile.h"
+
+#include <stdarg.h>
+
+#ifdef XP_WIN
+#include <windows.h>
+#include <io.h>
+#if defined(_MSC_VER) && _MSC_VER < 1900
+#define snprintf _snprintf
+#define vsnprintf _vsnprintf
+#endif
+#define strcasecmp _stricmp
+#define PATH_SEPARATOR_CHAR '\\'
+#define R_OK 04
+#elif defined(XP_MACOSX)
+#include <unistd.h>
+#include <sys/stat.h>
+#include <CoreFoundation/CoreFoundation.h>
+#define PATH_SEPARATOR_CHAR '/'
+#else
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#define PATH_SEPARATOR_CHAR '/'
+#endif
+
+#ifdef XP_WIN
+#define XRE_DONT_PROTECT_DLL_LOAD
+#include "nsWindowsWMain.cpp"
+#endif
+
+#define VERSION_MAXLEN 128
+
+static void Output(bool isError, const char *fmt, ... )
+{
+ va_list ap;
+ va_start(ap, fmt);
+
+#if (defined(XP_WIN) && !MOZ_WINCONSOLE)
+ char msg[2048];
+
+ vsnprintf(msg, sizeof(msg), fmt, ap);
+
+ UINT flags = MB_OK;
+ if (isError)
+ flags |= MB_ICONERROR;
+ else
+ flags |= MB_ICONINFORMATION;
+
+ wchar_t wide_msg[1024];
+ MultiByteToWideChar(CP_ACP,
+ 0,
+ msg,
+ -1,
+ wide_msg,
+ sizeof(wide_msg) / sizeof(wchar_t));
+
+ MessageBoxW(nullptr, wide_msg, L"XULRunner", flags);
+#else
+ vfprintf(stderr, fmt, ap);
+#endif
+
+ va_end(ap);
+}
+
+/**
+ * Return true if |arg| matches the given argument name.
+ */
+static bool IsArg(const char* arg, const char* s)
+{
+ if (*arg == '-')
+ {
+ if (*++arg == '-')
+ ++arg;
+ return !strcasecmp(arg, s);
+ }
+
+#if defined(XP_WIN)
+ if (*arg == '/')
+ return !strcasecmp(++arg, s);
+#endif
+
+ return false;
+}
+
+/**
+ * Return true if |aDir| is a valid file/directory.
+ */
+static bool FolderExists(const char* aDir)
+{
+#ifdef XP_WIN
+ wchar_t wideDir[MAX_PATH];
+ MultiByteToWideChar(CP_UTF8, 0, aDir, -1, wideDir, MAX_PATH);
+ DWORD fileAttrs = GetFileAttributesW(wideDir);
+ return fileAttrs != INVALID_FILE_ATTRIBUTES;
+#else
+ return access(aDir, R_OK) == 0;
+#endif
+}
+
+static nsresult GetRealPath(const char* appDataFile, char* *aResult)
+{
+#ifdef XP_WIN
+ wchar_t wAppDataFile[MAX_PATH];
+ wchar_t wIniPath[MAX_PATH];
+ MultiByteToWideChar(CP_UTF8, 0, appDataFile, -1, wAppDataFile, MAX_PATH);
+ _wfullpath(wIniPath, wAppDataFile, MAX_PATH);
+ WideCharToMultiByte(CP_UTF8, 0, wIniPath, -1, *aResult, MAX_PATH, 0, 0);
+#else
+ struct stat fileStat;
+ if (!realpath(appDataFile, *aResult) || stat(*aResult, &fileStat))
+ return NS_ERROR_FAILURE;
+#endif
+ if (!*aResult || !**aResult)
+ return NS_ERROR_FAILURE;
+
+ return NS_OK;
+}
+
+class AutoAppData
+{
+public:
+ AutoAppData(nsIFile* aINIFile) : mAppData(nullptr) {
+ nsresult rv = XRE_CreateAppData(aINIFile, &mAppData);
+ if (NS_FAILED(rv))
+ mAppData = nullptr;
+ }
+ ~AutoAppData() {
+ if (mAppData)
+ XRE_FreeAppData(mAppData);
+ }
+
+ operator nsXREAppData*() const { return mAppData; }
+ nsXREAppData* operator -> () const { return mAppData; }
+
+private:
+ nsXREAppData* mAppData;
+};
+
+XRE_CreateAppDataType XRE_CreateAppData;
+XRE_FreeAppDataType XRE_FreeAppData;
+XRE_mainType XRE_main;
+
+int
+main(int argc, char **argv)
+{
+ nsresult rv;
+ char *lastSlash;
+
+ char iniPath[MAXPATHLEN];
+ char tmpPath[MAXPATHLEN];
+ char greDir[MAXPATHLEN];
+ bool greFound = false;
+
+#if defined(XP_MACOSX)
+ CFBundleRef appBundle = CFBundleGetMainBundle();
+ if (!appBundle)
+ return 1;
+
+ CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL(appBundle);
+ if (!resourcesURL)
+ return 1;
+
+ CFURLRef absResourcesURL = CFURLCopyAbsoluteURL(resourcesURL);
+ CFRelease(resourcesURL);
+ if (!absResourcesURL)
+ return 1;
+
+ CFURLRef iniFileURL =
+ CFURLCreateCopyAppendingPathComponent(kCFAllocatorDefault,
+ absResourcesURL,
+ CFSTR("application.ini"),
+ false);
+ CFRelease(absResourcesURL);
+ if (!iniFileURL)
+ return 1;
+
+ CFStringRef iniPathStr =
+ CFURLCopyFileSystemPath(iniFileURL, kCFURLPOSIXPathStyle);
+ CFRelease(iniFileURL);
+ if (!iniPathStr)
+ return 1;
+
+ CFStringGetCString(iniPathStr, iniPath, sizeof(iniPath),
+ kCFStringEncodingUTF8);
+ CFRelease(iniPathStr);
+
+#else
+
+#ifdef XP_WIN
+ wchar_t wide_path[MAX_PATH];
+ if (!::GetModuleFileNameW(nullptr, wide_path, MAX_PATH))
+ return 1;
+
+ WideCharToMultiByte(CP_UTF8, 0, wide_path,-1,
+ iniPath, MAX_PATH, nullptr, nullptr);
+
+#else
+ // on unix, there is no official way to get the path of the current binary.
+ // instead of using the MOZILLA_FIVE_HOME hack, which doesn't scale to
+ // multiple applications, we will try a series of techniques:
+ //
+ // 1) use realpath() on argv[0], which works unless we're loaded from the
+ // PATH
+ // 2) manually walk through the PATH and look for ourself
+ // 3) give up
+
+ struct stat fileStat;
+ strncpy(tmpPath, argv[0], sizeof(tmpPath));
+ lastSlash = strrchr(tmpPath, '/');
+ if (lastSlash) {
+ *lastSlash = 0;
+ realpath(tmpPath, iniPath);
+ } else {
+ const char *path = getenv("PATH");
+ if (!path)
+ return 1;
+
+ char *pathdup = strdup(path);
+ if (!pathdup)
+ return 1;
+
+ bool found = false;
+ char *token = strtok(pathdup, ":");
+ while (token) {
+ sprintf(tmpPath, "%s/%s", token, argv[0]);
+ if (stat(tmpPath, &fileStat) == 0) {
+ found = true;
+ lastSlash = strrchr(tmpPath, '/');
+ *lastSlash = 0;
+ realpath(tmpPath, iniPath);
+ break;
+ }
+ token = strtok(nullptr, ":");
+ }
+ free (pathdup);
+ if (!found)
+ return 1;
+ }
+ lastSlash = iniPath + strlen(iniPath);
+ *lastSlash = '/';
+#endif
+
+#ifndef XP_UNIX
+ lastSlash = strrchr(iniPath, PATH_SEPARATOR_CHAR);
+ if (!lastSlash)
+ return 1;
+#endif
+
+ *(++lastSlash) = '\0';
+
+ // On Linux/Win, look for XULRunner in appdir/xulrunner
+
+ snprintf(greDir, sizeof(greDir),
+ "%sxulrunner" XPCOM_FILE_PATH_SEPARATOR XPCOM_DLL,
+ iniPath);
+
+ greFound = FolderExists(greDir);
+
+#ifdef XP_UNIX
+ if (greFound) {
+ char resolved_greDir[MAXPATHLEN] = "";
+ if (realpath(greDir, resolved_greDir) && *resolved_greDir) {
+ strncpy(greDir, resolved_greDir, MAXPATHLEN);
+ }
+ }
+#endif
+
+ strncpy(lastSlash, "application.ini", sizeof(iniPath) - (lastSlash - iniPath));
+
+#endif
+
+ // If -app parameter was passed in, it is now time to take it under
+ // consideration.
+ const char *appDataFile;
+ appDataFile = getenv("XUL_APP_FILE");
+ if (!appDataFile || !*appDataFile)
+ if (argc > 1 && IsArg(argv[1], "app")) {
+ if (argc == 2) {
+ Output(false, "specify APP-FILE (optional)\n");
+ return 1;
+ }
+ argv[1] = argv[0];
+ ++argv;
+ --argc;
+
+ appDataFile = argv[1];
+ argv[1] = argv[0];
+ ++argv;
+ --argc;
+
+ char kAppEnv[MAXPATHLEN];
+ snprintf(kAppEnv, MAXPATHLEN, "XUL_APP_FILE=%s", appDataFile);
+ if (putenv(kAppEnv))
+ Output(false, "Couldn't set %s.\n", kAppEnv);
+
+ char *result = (char*) calloc(sizeof(char), MAXPATHLEN);
+ if (NS_FAILED(GetRealPath(appDataFile, &result))) {
+ Output(true, "Invalid application.ini path.\n");
+ return 1;
+ }
+
+ // We have a valid application.ini path passed in to the -app parameter
+ // but not yet a valid greDir, so lets look for it also on the same folder
+ // as the stub.
+ if (!greFound) {
+ lastSlash = strrchr(iniPath, PATH_SEPARATOR_CHAR);
+ if (!lastSlash)
+ return 1;
+
+ *(++lastSlash) = '\0';
+
+ snprintf(greDir, sizeof(greDir), "%s" XPCOM_DLL, iniPath);
+ greFound = FolderExists(greDir);
+ }
+
+ // copy it back.
+ strcpy(iniPath, result);
+ }
+
+ nsINIParser parser;
+ rv = parser.Init(iniPath);
+ if (NS_FAILED(rv)) {
+ fprintf(stderr, "Could not read application.ini\n");
+ return 1;
+ }
+
+ if (!greFound) {
+#ifdef XP_MACOSX
+ // The bundle can be found next to the executable, in the MacOS dir.
+ CFURLRef exurl = CFBundleCopyExecutableURL(appBundle);
+ CFURLRef absexurl = nullptr;
+ if (exurl) {
+ absexurl = CFURLCopyAbsoluteURL(exurl);
+ CFRelease(exurl);
+ }
+
+ if (absexurl) {
+ char tbuffer[MAXPATHLEN];
+
+ if (CFURLGetFileSystemRepresentation(absexurl, true,
+ (UInt8*) tbuffer,
+ sizeof(tbuffer)) &&
+ access(tbuffer, R_OK | X_OK) == 0) {
+ if (realpath(tbuffer, greDir)) {
+ greFound = true;
+ }
+ else {
+ greDir[0] = '\0';
+ }
+ }
+
+ CFRelease(absexurl);
+ }
+#endif
+ if (!greFound) {
+ Output(false, "Could not find the Mozilla runtime.\n");
+ return 1;
+ }
+ }
+
+ rv = XPCOMGlueStartup(greDir);
+ if (NS_FAILED(rv)) {
+ if (rv == NS_ERROR_OUT_OF_MEMORY) {
+ char applicationName[2000] = "this application";
+ parser.GetString("App", "Name", applicationName, sizeof(applicationName));
+ Output(true, "Not enough memory available to start %s.\n",
+ applicationName);
+ } else {
+ Output(true, "Couldn't load XPCOM.\n");
+ }
+ return 1;
+ }
+
+ static const nsDynamicFunctionLoad kXULFuncs[] = {
+ { "XRE_CreateAppData", (NSFuncPtr*) &XRE_CreateAppData },
+ { "XRE_FreeAppData", (NSFuncPtr*) &XRE_FreeAppData },
+ { "XRE_main", (NSFuncPtr*) &XRE_main },
+ { nullptr, nullptr }
+ };
+
+ rv = XPCOMGlueLoadXULFunctions(kXULFuncs);
+ if (NS_FAILED(rv)) {
+ Output(true, "Couldn't load XRE functions.\n");
+ return 1;
+ }
+
+ NS_LogInit();
+
+ int retval;
+
+ { // Scope COMPtr and AutoAppData
+ nsCOMPtr<nsIFile> iniFile;
+#ifdef XP_WIN
+ // On Windows iniPath is UTF-8 encoded so we need to convert it.
+ rv = NS_NewLocalFile(NS_ConvertUTF8toUTF16(iniPath), false,
+ getter_AddRefs(iniFile));
+#else
+ rv = NS_NewNativeLocalFile(nsDependentCString(iniPath), false,
+ getter_AddRefs(iniFile));
+#endif
+ if (NS_FAILED(rv)) {
+ Output(true, "Couldn't find application.ini file.\n");
+ return 1;
+ }
+
+ AutoAppData appData(iniFile);
+ if (!appData) {
+ Output(true, "Error: couldn't parse application.ini.\n");
+ return 1;
+ }
+
+ NS_ASSERTION(appData->directory, "Failed to get app directory.");
+
+ if (!appData->xreDirectory) {
+ // chop "libxul.so" off the GRE path
+ lastSlash = strrchr(greDir, PATH_SEPARATOR_CHAR);
+ if (lastSlash) {
+ *lastSlash = '\0';
+ }
+#ifdef XP_WIN
+ // same as iniPath.
+ NS_NewLocalFile(NS_ConvertUTF8toUTF16(greDir), false,
+ &appData->xreDirectory);
+#else
+ NS_NewNativeLocalFile(nsDependentCString(greDir), false,
+ &appData->xreDirectory);
+#endif
+ }
+
+ retval = XRE_main(argc, argv, appData, 0);
+ }
+
+ NS_LogTerm();
+
+ return retval;
+}
diff --git a/xulrunner/stub/xulrunner-stub.exe.manifest b/xulrunner/stub/xulrunner-stub.exe.manifest
new file mode 100644
index 000000000..57c2a7070
--- /dev/null
+++ b/xulrunner/stub/xulrunner-stub.exe.manifest
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+<assemblyIdentity
+ version="1.0.0.0"
+ processorArchitecture="*"
+ name="Mozilla.XULRunner.Stub"
+ type="win32"
+/>
+<description>Mozilla XULRunner Stub</description>
+<dependency>
+ <dependentAssembly>
+ <assemblyIdentity
+ type="win32"
+ name="Microsoft.Windows.Common-Controls"
+ version="6.0.0.0"
+ processorArchitecture="*"
+ publicKeyToken="6595b64144ccf1df"
+ language="*"
+ />
+ </dependentAssembly>
+</dependency>
+<ms_asmv3:trustInfo xmlns:ms_asmv3="urn:schemas-microsoft-com:asm.v3">
+ <ms_asmv3:security>
+ <ms_asmv3:requestedPrivileges>
+ <ms_asmv3:requestedExecutionLevel level="asInvoker" uiAccess="false" />
+ </ms_asmv3:requestedPrivileges>
+ </ms_asmv3:security>
+</ms_asmv3:trustInfo>
+ <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
+ <application>
+ <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
+ <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
+ <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
+ <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
+ <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
+ </application>
+ </compatibility>
+</assembly>
diff --git a/xulrunner/stub/xulrunner-stub.rc b/xulrunner/stub/xulrunner-stub.rc
new file mode 100644
index 000000000..84c3e47ed
--- /dev/null
+++ b/xulrunner/stub/xulrunner-stub.rc
@@ -0,0 +1,6 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+1 24 "xulrunner-stub.exe.manifest"