Bug 224305 part "windows" - Separate GRE (xulrunner) registration from the installer scripts, r=darin a=asa

This commit is contained in:
bsmedberg%covad.net 2005-06-10 19:21:27 +00:00
Родитель 49e6923085
Коммит f290a07e0f
17 изменённых файлов: 1060 добавлений и 402 удалений

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

@ -989,13 +989,59 @@ RemoteCommandLine()
}
#endif // MOZ_ENABLE_XREMOTE
#if defined(XP_UNIX) && !defined(XP_MACOSX)
char gBinaryPath[MAXPATHLEN];
static PRBool
GetBinaryPath(const char* argv0)
nsresult
XRE_GetBinaryPath(const char* argv0, nsILocalFile* *aResult)
{
nsresult rv;
nsCOMPtr<nsILocalFile> lf;
// We need to use platform-specific hackery to find the
// path of this executable. This is copied, with some modifications, from
// nsGREDirServiceProvider.cpp
#ifdef XP_WIN
char exePath[MAXPATHLEN];
if (!::GetModuleFileName(0, exePath, MAXPATHLEN))
return NS_ERROR_FAILURE;
rv = NS_NewNativeLocalFile(nsDependentCString(exePath), PR_TRUE,
getter_AddRefs(lf));
if (NS_FAILED(rv))
return rv;
#elif defined(XP_MACOSX)
NS_NewNativeLocalFile(EmptyCString(), PR_TRUE, getter_AddRefs(lf));
nsCOMPtr<nsILocalFileMac> lfm (do_QueryInterface(lf));
if (!lfm)
return NS_ERROR_FAILURE;
// Works even if we're not bundled.
CFBundleRef appBundle = CFBundleGetMainBundle();
if (!appBundle)
return NS_ERROR_FAILURE;
CFURLRef bundleURL = CFBundleCopyExecutableURL(appBundle);
if (!bundleURL)
return NS_ERROR_FAILURE;
FSRef fileRef;
if (!CFURLGetFSRef(bundleURL, &fileRef)) {
CFRelease(bundleURL);
return NS_ERROR_FAILURE;
}
nsresult rv = lfm->InitWithFSRef(fileRef);
CFRelease(bundleURL);
if (NS_FAILED(rv))
return rv;
#elif defined(XP_UNIX)
struct stat fileStat;
const char exePath[MAXPATHLEN];
rv = NS_ERROR_FAILURE;
// 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
@ -1010,87 +1056,59 @@ GetBinaryPath(const char* argv0)
// #ifdef __linux__
#if 0
int r = readlink("/proc/self/exe", gBinaryPath, MAXPATHLEN);
int r = readlink("/proc/self/exe", exePath, MAXPATHLEN);
// apparently, /proc/self/exe can sometimes return weird data... check it
if (r > 0 && r < MAXPATHLEN && stat(gBinaryPath, &fileStat) == 0)
return PR_TRUE;
if (r > 0 && r < MAXPATHLEN && stat(exePath, &fileStat) == 0) {
rv = NS_OK;
}
#endif
if (NS_FAILED(rv) &&
realpath(argv0, exePath) && stat(exePath, &fileStat) == 0) {
rv = NS_OK;
}
if (realpath(argv0, gBinaryPath) && stat(gBinaryPath, &fileStat) == 0)
return PR_TRUE;
if (NS_FAILED(rv)) {
const char *path = getenv("PATH");
if (!path)
return NS_ERROR_FAILURE;
const char *path = getenv("PATH");
if (!path) return PR_FALSE;
char *pathdup = strdup(path);
if (!pathdup)
return NS_ERROR_OUT_OF_MEMORY;
char *pathdup = strdup(path);
if (!pathdup) return PR_FALSE;
PRBool found = PR_FALSE;
char *newStr = pathdup;
char *token;
while ( (token = nsCRT::strtok(newStr, ":", &newStr)) ) {
sprintf(gBinaryPath, "%s/%s", token, argv0);
if (stat(gBinaryPath, &fileStat) == 0) {
found = PR_TRUE;
break;
PRBool found = PR_FALSE;
char *newStr = pathdup;
char *token;
while ( (token = nsCRT::strtok(newStr, ":", &newStr)) ) {
sprintf(exePath, "%s/%s", token, argv0);
if (stat(exePath, &fileStat) == 0) {
found = PR_TRUE;
break;
}
}
}
free(pathdup);
return found;
}
#endif
#define NS_ERROR_LAUNCHED_CHILD_PROCESS NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_PROFILE, 200)
static nsresult LaunchChild(nsINativeAppSupport* aNative)
{
aNative->Quit(); // release DDE mutex, if we're holding it
// We need to use platform-specific hackery to find the
// path of this executable. This is copied, with some modifications, from
// nsGREDirServiceProvider.cpp
#ifdef XP_WIN
// We must shorten the path to a 8.3 path, since that's all _execv can
// handle (otherwise segments after any spaces that might exist in the path
// will be converted into parameters, and really weird things will happen)
char exePath[MAXPATHLEN];
if (!::GetModuleFileName(0, exePath, MAXPATHLEN) ||
!::GetShortPathName(exePath, exePath, sizeof(exePath)))
return NS_ERROR_FAILURE;
gRestartArgv[0] = (char*)exePath;
#elif defined(XP_MACOSX)
// Works even if we're not bundled.
CFBundleRef appBundle = CFBundleGetMainBundle();
if (!appBundle) return NS_ERROR_FAILURE;
CFURLRef bundleURL = CFBundleCopyExecutableURL(appBundle);
if (!bundleURL) return NS_ERROR_FAILURE;
FSRef fileRef;
if (!CFURLGetFSRef(bundleURL, &fileRef)) {
CFRelease(bundleURL);
return NS_ERROR_FAILURE;
free(pathdup);
if (!found)
return NS_ERROR_FAILURE;
}
char exePath[MAXPATHLEN];
if (FSRefMakePath(&fileRef, exePath, MAXPATHLEN)) {
CFRelease(bundleURL);
return NS_ERROR_FAILURE;
}
CFRelease(bundleURL);
#elif defined(XP_UNIX)
char* exePath = gBinaryPath;
rv = NS_NewNativeLocalFile(nsDependentCString(exePath), PR_TRUE,
getter_AddRefs(lf));
if (NS_FAILED(rv))
return rv;
#elif defined(XP_OS2)
PPIB ppib;
PTIB ptib;
char exePath[MAXPATHLEN];
DosGetInfoBlocks( &ptib, &ppib);
DosQueryModuleName( ppib->pib_hmte, MAXPATHLEN, exePath);
rv = NS_NewNativeLocalFile(nsDependentCString(exePath), PR_TRUE,
getter_AddRefs(lf));
if (NS_FAILED(rv))
return rv;
#elif defined(XP_BEOS)
int32 cookie = 0;
@ -1099,24 +1117,61 @@ static nsresult LaunchChild(nsINativeAppSupport* aNative)
if(get_next_image_info(0, &cookie, &info) != B_OK)
return NS_ERROR_FAILURE;
char *exePath = info.name;
PL_strncpy(aResult, info.name, MAXPATHLEN);
rv = NS_NewNativeLocalFile(nsDependentCString(info.name), PR_TRUE,
getter_AddRefs(lf));
if (NS_FAILED(rv))
return rv;
#elif
#error Oops, you need platform-specific code here
#endif
// restart this process by exec'ing it into the current process
// if supported by the platform. otherwise, use nspr ;-)
NS_ADDREF(*aResult = lf);
return NS_OK;
}
#if defined(XP_WIN) || defined(XP_OS2)
if (_execv(exePath, gRestartArgv) == -1)
return NS_ERROR_FAILURE;
#elif defined(XP_MACOSX)
#define NS_ERROR_LAUNCHED_CHILD_PROCESS NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_PROFILE, 200)
static nsresult LaunchChild(nsINativeAppSupport* aNative)
{
aNative->Quit(); // release DDE mutex, if we're holding it
// Restart this process by exec'ing it into the current process
// if supported by the platform. Otherwise, use NSPR.
#if defined(XP_MACOSX)
LaunchChildMac(gRestartArgc, gRestartArgv);
#else
nsCOMPtr<nsILocalFile> lf;
nsresult rv = XRE_GetBinaryPath(gArgv[0], getter_AddRefs(lf));
if (NS_FAILED(rv))
return rv;
nsCAutoString exePath;
rv = lf->GetNativePath(exePath);
if (NS_FAILED(rv))
return rv;
#if defined(XP_WIN)
// We must shorten the path to a 8.3 path, since that's all _execv can
// handle (otherwise segments after any spaces that might exist in the path
// will be converted into parameters, and really weird things will happen)
char shortPath[MAXPATHLEN];
::GetShortPathName(exePath.get(), shortPath, MAXPATHLEN);
gRestartArgv[0] = shortPath;
if (_execv(shortPath, gRestartArgv) == -1)
return NS_ERROR_FAILURE;
#elif defined(XP_OS2)
if (_execv(exePath.get(), gRestartArgv) == -1)
return NS_ERROR_FAILURE;
#elif defined(XP_UNIX)
if (execv(exePath, gRestartArgv) == -1)
if (execv(exePath.get(), gRestartArgv) == -1)
return NS_ERROR_FAILURE;
#else
PRProcess* process = PR_CreateProcess(exePath, gRestartArgv,
PRProcess* process = PR_CreateProcess(exePath.get(), gRestartArgv,
nsnull, nsnull);
if (!process) return NS_ERROR_FAILURE;
@ -1124,6 +1179,7 @@ static nsresult LaunchChild(nsINativeAppSupport* aNative)
PRStatus failed = PR_WaitProcess(process, &exitCode);
if (failed || exitCode)
return NS_ERROR_FAILURE;
#endif
#endif
return NS_ERROR_LAUNCHED_CHILD_PROCESS;
@ -1681,11 +1737,6 @@ XRE_main(int argc, char* argv[], const nsXREAppData* aAppData)
fpsetmask(0);
#endif
#if defined(XP_UNIX) && !defined(XP_MACOSX)
if (!GetBinaryPath(argv[0]))
return 1;
#endif
gArgc = argc;
gArgv = argv;
@ -1724,11 +1775,6 @@ XRE_main(int argc, char* argv[], const nsXREAppData* aAppData)
ScopedFPHandler handler;
#endif /* XP_OS2 */
#ifdef _BUILD_STATIC_BIN
// Initialize XPCOM's module info table
NSGetStaticModuleInfo = app_getModuleInfo;
#endif
if (CheckArg("safe-mode"))
gSafeMode = PR_TRUE;

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

@ -75,10 +75,6 @@ extern int gArgc;
extern char **gArgv;
extern PRBool gLogConsoleErrors;
#if defined(XP_UNIX) && !defined(XP_MACOSX)
extern char gBinaryPath[MAXPATHLEN];
#endif
/**
* Create the nativeappsupport implementation.
*

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

@ -110,88 +110,21 @@ 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
#ifdef XP_WIN
char exePath[MAXPATHLEN];
if ( ! ::GetModuleFileName(0, exePath, MAXPATHLEN) )
nsCOMPtr<nsILocalFile> lf;
nsresult rv = XRE_GetBinaryPath(gArgv[0], getter_AddRefs(lf));
if (NS_FAILED(rv))
return rv;
nsCOMPtr<nsIFile> appDir;
rv = lf->GetParent(getter_AddRefs(appDir));
if (NS_FAILED(rv))
return rv;
mAppDir = do_QueryInterface(appDir);
if (!mAppDir)
return NS_ERROR_FAILURE;
// chop off the executable name by finding the rightmost backslash
char* lastSlash = strrchr(exePath, '\\');
if (!lastSlash) return NS_ERROR_FAILURE;
*(lastSlash) = '\0';
return NS_NewNativeLocalFile(nsDependentCString(exePath), PR_TRUE,
getter_AddRefs(mAppDir));
#elif defined(XP_MACOSX)
// Works even if we're not bundled.
CFBundleRef appBundle = CFBundleGetMainBundle();
if (!appBundle) return NS_ERROR_FAILURE;
nsresult rv = NS_ERROR_FAILURE;
CFURLRef bundleURL = CFBundleCopyExecutableURL(appBundle);
if (bundleURL) {
CFURLRef parentURL = CFURLCreateCopyDeletingLastPathComponent(kCFAllocatorDefault, bundleURL);
if (parentURL) {
rv = NS_NewNativeLocalFile(EmptyCString(), PR_TRUE,
getter_AddRefs(mAppDir));
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsILocalFileMac> appDirMac (do_QueryInterface(mAppDir, &rv));
if (NS_SUCCEEDED(rv)) {
rv = appDirMac->InitWithCFURL(parentURL);
}
}
CFRelease(parentURL);
}
CFRelease(bundleURL);
}
return rv;
#elif defined(XP_UNIX)
// Because we do have access to argv[0], we can get the application
// path with certitude, instead of using MOZILLA_FIVE_HOME or
// guessing from the CWD like nsGREDirServiceProvider does.
char* lastSlash = strrchr(gBinaryPath, '/');
if (!lastSlash) return NS_ERROR_FAILURE;
nsDependentCSubstring appDir(gBinaryPath, lastSlash);
return NS_NewNativeLocalFile(appDir, PR_TRUE, getter_AddRefs(mAppDir));
#elif defined(XP_OS2)
PPIB ppib;
PTIB ptib;
char appDir[MAXPATHLEN];
char* p;
DosGetInfoBlocks( &ptib, &ppib);
DosQueryModuleName( ppib->pib_hmte, MAXPATHLEN, appDir);
p = strrchr( appDir, '\\'); // XXX DBCS misery
if (!p) return NS_ERROR_FAILURE;
*p = '\0';
return NS_NewNativeLocalFile(nsDependentCString(appDir), PR_TRUE, getter_AddRefs(mAppDir));
#elif defined(XP_BEOS)
int32 cookie = 0;
image_info info;
char *p;
if(get_next_image_info(0, &cookie, &info) != B_OK)
return NS_ERROR_FAILURE;
p = strrchr(info.name, '/');
if (!p) return NS_ERROR_FAILURE;
*p = 0;
return NS_NewNativeLocalFile(nsDependentCString(info.name), PR_TRUE, getter_AddRefs(mAppDir));
#elif
#error Oops, you need platform-specific code here
#endif
return NS_OK;
}
nsresult

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

@ -189,4 +189,13 @@ XRE_main(int argc, char* argv[],
extern "C" XULAPI nsresult
XRE_GetFileFromPath(const char *aPath, nsILocalFile* *aResult);
/**
* Get the path of the running application binary and store it in aResult.
* @param argv0 The value passed as argv[0] of main(). This value is only
* used on *nix, and only when other methods of determining
* the binary path have failed.
*/
extern "C" XULAPI nsresult
XRE_GetBinaryPath(const char *argv0, nsILocalFile* *aResult);
#endif // _nsXULAppAPI_h__

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

@ -39,6 +39,7 @@
// the dll that are located in the .lib files we link with
#include <windows.h>
#include "nsXPCOMGlue.h"
#include "nsVoidArray.h"
#include "nsValueArray.h"
#include "nsIAtom.h"
@ -99,6 +100,7 @@
void XXXNeverCalled()
{
GRE_GetGREPathForVersion(nsnull, nsnull, 0);
nsTextFormatter::snprintf(nsnull,0,nsnull);
nsTextFormatter::smprintf(nsnull, nsnull);
nsTextFormatter::smprintf_free(nsnull);

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

@ -195,7 +195,7 @@ NS_GetFrozenFunctions(XPCOMFunctions *entryPoints, const char* libraryPath);
#define XPCOM_SEARCH_KEY "PATH"
#define GRE_CONF_NAME "gre.config"
#define GRE_WIN_REG_LOC "Software\\mozilla.org\\GRE\\"
#define GRE_WIN_REG_LOC "Software\\mozilla.org\\GRE"
#define XPCOM_DLL "xpcom.dll"
#elif defined(XP_BEOS)
@ -231,6 +231,16 @@ NS_GetFrozenFunctions(XPCOMFunctions *entryPoints, const char* libraryPath);
#error need_to_define_your_file_path_separator_and_illegal_characters
#endif
#ifndef MAXPATHLEN
#ifdef _MAX_PATH
#define MAXPATHLEN _MAX_PATH
#elif defined(CCHMAXPATH)
#define MAXPATHLEN CCHMAXPATH
#else
#define MAXPATHLEN 1024
#endif
#endif
#endif

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

@ -66,7 +66,15 @@ SDK_HEADERS = \
nsISupportsImpl.h \
nsISupportsUtils.h \
nsIWeakReferenceUtils.h \
$(XPCOM_GLUE_SRC_LEXPORTS) \
nsCOMPtr.h \
nsDebug.h \
nsGenericFactory.h \
nsIGenericFactory.h \
nsMemory.h \
nsTraceRefcnt.h \
nsWeakReference.h \
nsComponentManagerUtils.h \
nsServiceManagerUtils.h \
$(NULL)
SDK_LIBRARY = \

359
xpcom/glue/nsGREGlue.cpp Executable file
Просмотреть файл

@ -0,0 +1,359 @@
/* -*- 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>
* Benjamin Smedberg <benjamin@smedbergs.us>
*
* 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 "nsXPCOMPrivate.h"
#include "nsXPCOMGlue.h"
#include <stdio.h>
#include <stdlib.h>
#include "prenv.h"
#include "prio.h"
#include "plstr.h"
#ifdef XP_WIN32
# include <windows.h>
# include <mbstring.h>
# include <io.h>
# define snprintf _snprintf
# define R_OK 04
#elif defined(XP_OS2)
# define INCL_DOS
# include <os2.h>
#elif defined(XP_MACOSX)
# include <Processes.h>
# include <CFBundle.h>
#elif defined(XP_UNIX)
# include <unistd.h>
# include <sys/param.h>
#elif defined(XP_BEOS)
# include <FindDirectory.h>
# include <Path.h>
# include <unistd.h>
# include <sys/param.h>
# include <OS.h>
# include <image.h>
#endif
#include <sys/stat.h>
static PRBool
GRE_GetPathFromConfigDir(const char* version, const char* dirname,
char* buffer, PRUint32 buflen);
static PRBool
GRE_GetPathFromConfigFile(const char* version, const char* dirname,
char* buffer, PRUint32 buflen);
#ifdef XP_WIN
static PRBool
GRE_GetPathFromRegKey(const char* version, HKEY aRegKey,
char* buffer, PRUint32 buflen);
#endif
nsresult
GRE_GetGREPathForVersion(const char *aVersion,
char *aBuffer, PRUint32 aBufLen)
{
// 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, aBuffer))
return NS_OK;
#elif XP_WIN32
if (_fullpath(aBuffer, env, aBufLen))
return NS_OK;
#else
// hope for the best
// xxxbsmedberg: other platforms should have a "make absolute" function
#endif
if (strlen(env) >= aBufLen)
return NS_ERROR_FILE_NAME_TOO_LONG;
strcpy(aBuffer, env);
return NS_OK;
}
// the Gecko bits that sit next to the application or in the LD_LIBRARY_PATH
env = PR_GetEnv("USE_LOCAL_GRE");
if (env && *env) {
*aBuffer = nsnull;
return NS_OK;
}
env = PR_GetEnv("MOZ_GRE_CONF");
if (env && GRE_GetPathFromConfigFile(aVersion, env, aBuffer, aBufLen)) {
return NS_OK;
}
#if XP_UNIX
// check in the HOME directory
env = PR_GetEnv("HOME");
if (env && *env) {
char buffer[MAXPATHLEN];
sprintf(buffer, "%s" XPCOM_FILE_PATH_SEPARATOR GRE_CONF_NAME, env);
if (GRE_GetPathFromConfigFile(aVersion, buffer, aBuffer, aBufLen)) {
return NS_OK;
}
}
#endif
#if XP_UNIX
// Look for a global /etc/gre.conf file
if (GRE_GetPathFromConfigFile(aVersion, GRE_CONF_PATH, aBuffer, aBufLen)) {
return NS_OK;
}
// Look for a group of config files in /etc/gre.d/
if (GRE_GetPathFromConfigDir(aVersion, GRE_CONF_DIR, aBuffer, aBufLen)) {
return NS_OK;
}
#endif
#if XP_WIN32
HKEY hRegKey = 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/GRE.html for
// more info.
//
if (::RegOpenKeyEx(HKEY_CURRENT_USER, GRE_WIN_REG_LOC, 0,
KEY_READ, &hRegKey) == ERROR_SUCCESS) {
PRBool ok = GRE_GetPathFromRegKey(aVersion, hRegKey, aBuffer, aBufLen);
::RegCloseKey(hRegKey);
if (ok)
return NS_OK;
}
if (::RegOpenKeyEx(HKEY_LOCAL_MACHINE, GRE_WIN_REG_LOC, 0,
KEY_ENUMERATE_SUB_KEYS, &hRegKey) == ERROR_SUCCESS) {
PRBool ok = GRE_GetPathFromRegKey(aVersion, hRegKey, aBuffer, aBufLen);
::RegCloseKey(hRegKey);
if (ok)
return NS_OK;
}
#endif
return NS_ERROR_FAILURE;
}
PRBool
GRE_GetPathFromConfigDir(const char* version, const char* dirname,
char* buffer, PRUint32 buflen)
{
// 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))) {
const char kExt[] = ".conf";
// Only look for files that end in .conf
char *offset = PL_strrstr(entry->name, kExt);
if (!offset)
continue;
if (offset != entry->name + strlen(entry->name) - (sizeof(kExt) - 1))
continue;
char fullPath[MAXPATHLEN];
snprintf(fullPath, MAXPATHLEN, "%s" XPCOM_FILE_PATH_SEPARATOR "%s",
dirname, entry->name);
found = GRE_GetPathFromConfigFile(version, fullPath, buffer, buflen);
}
PR_CloseDir(dir);
return found;
}
#define READ_BUFFER_SIZE 1024
PRBool
GRE_GetPathFromConfigFile(const char* version, const char* filename,
char* pathBuffer, PRUint32 buflen)
{
*pathBuffer = '\0';
char buffer[READ_BUFFER_SIZE];
FILE *cfg;
PRBool foundHeader = PR_FALSE;
if ((cfg = fopen(filename,"r")) == nsnull) {
return nsnull;
}
while (fgets(buffer, READ_BUFFER_SIZE, 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 (!strcmp(buffer+1, version)) {
foundHeader = PR_TRUE;
}
continue;
}
if (foundHeader && !strncmp (buffer, "GRE_PATH=", 9)) {
strncpy(pathBuffer, buffer + 9, buflen);
// kill the line feed if any
PRInt32 len = strlen(pathBuffer);
len--;
if (pathBuffer[len] == '\n')
pathBuffer[len] = '\0';
break;
}
}
fclose(cfg);
return (*pathBuffer != '\0');
}
#ifdef XP_WIN
static PRBool
CopyWithEnvExpansion(char* aDest, const char* aSource, PRUint32 aBufLen,
DWORD aType)
{
switch (aType) {
case REG_SZ:
if (strlen(aSource) >= aBufLen)
return PR_FALSE;
strcpy(aDest, aSource);
return PR_TRUE;
case REG_EXPAND_SZ:
if (ExpandEnvironmentStrings(aSource, aDest, aBufLen) > aBufLen)
return PR_FALSE;
return PR_TRUE;
};
// Whoops! We expected REG_SZ or REG_EXPAND_SZ, what happened here?
return PR_FALSE;
}
PRBool
GRE_GetPathFromRegKey(const char* aVersion, HKEY aRegKey,
char* aBuffer, PRUint32 aBufLen)
{
// Formerly, GREs were registered at the key HKLM/Software/Mozilla/GRE/<version>
// valuepair GreHome=Path. Nowadays, they are registered in any subkey of
// Software/Mozilla/GRE, with the following valuepairs:
// Version=<version> (REG_SZ)
// GreHome=<path> (REG_SZ or REG_EXPAND_SZ)
//
// Additional meta-info may be available in the future, including
// localization info, ABI, and other information which might be pertinent
// to selecting one GRE over another.
//
// When a GRE is being registered, it should try to register itself at
// HKLM/Software/Mozilla/GRE/<Version> first, to preserve compatibility
// with older glue. If this key is already taken (i.e. there is more than
// one GRE of that version installed), it should append a unique number to
// the version, for example:
// 1.1 (already in use), 1.1_1, 1.1_2, etc...
DWORD i = 0;
while (PR_TRUE) {
char name[MAXPATHLEN + 1];
DWORD nameLen = MAXPATHLEN;
if (::RegEnumKeyEx(aRegKey, i, name, &nameLen, NULL, NULL, NULL, NULL) !=
ERROR_SUCCESS) {
break;
}
HKEY subKey = NULL;
if (::RegOpenKeyEx(aRegKey, name, 0, KEY_QUERY_VALUE, &subKey) !=
ERROR_SUCCESS) {
continue;
}
char version[40];
DWORD versionlen = 40;
char pathbuf[MAXPATHLEN];
DWORD pathlen = MAXPATHLEN;
DWORD pathtype;
if (::RegQueryValueEx(subKey, "Version", NULL, NULL,
(BYTE*) version, &versionlen) == ERROR_SUCCESS &&
strncmp(aVersion, version, versionlen) == 0) {
if (::RegQueryValueEx(subKey, "GreHome", NULL, &pathtype,
(BYTE*) pathbuf, &pathlen) == ERROR_SUCCESS &&
*pathbuf &&
CopyWithEnvExpansion(aBuffer, pathbuf, aBufLen, pathtype) &&
access(aBuffer, R_OK) == 0) {
RegCloseKey(subKey);
return PR_TRUE;
}
}
RegCloseKey(subKey);
++i;
}
return PR_FALSE;
}
#endif // XP_WIN

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

@ -43,20 +43,7 @@ XPCOM_GLUE_SRC_LCSRCS = \
nsMemory.cpp \
nsTraceRefcnt.cpp \
nsWeakReference.cpp \
nsGREGlue.cpp \
$(NULL) \
XPCOM_GLUE_SRC_LEXPORTS = \
nsCOMPtr.h \
nsDebug.h \
nsGenericFactory.h \
nsIGenericFactory.h \
nsMemory.h \
nsTraceRefcnt.h \
nsWeakReference.h \
nsComponentManagerUtils.h \
nsServiceManagerUtils.h \
$(NULL)
XPCOM_GLUE_SRC_CSRCS := $(addprefix $(topsrcdir)/xpcom/glue/, $(XPCOM_GLUE_SRC_LCSRCS))

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

@ -21,6 +21,7 @@
*
* Contributor(s):
* Sean Su <ssu@netscape.com>
* Benjamin Smedberg <benjamin@smedbergs.us>
*
* 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
@ -82,9 +83,7 @@
#include "nsGREDirServiceProvider.h"
PRBool GRE_GetCurrentProcessDirectory(char* buffer);
PRBool GRE_GetPathFromConfigDir(const char* dirname, char* buffer);
PRBool GRE_GetPathFromConfigFile(const char* dirname, char* buffer);
static PRBool GRE_GetCurrentProcessDirectory(char* buffer);
//*****************************************************************************
// nsGREDirServiceProvider::nsISupports
@ -295,179 +294,13 @@ GRE_GetGREPath()
}
}
// 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);
#else
// hope for the best
strcpy(sGRELocation, env);
#endif
// xxxbsmedberg: it would help that other platforms had a "make absolute" function
GRE_GetGREPathForVersion(GRE_BUILD_ID, sGRELocation, MAXPATHLEN);
if (*sGRELocation)
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) {
sprintf(buffer, "%s" XPCOM_FILE_PATH_SEPARATOR GRE_CONF_NAME, env);
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)
{

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

@ -40,16 +40,6 @@
#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
*/

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

@ -20,6 +20,7 @@
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Benjamin Smedberg <benjamin@smedbergs.us>
*
* 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"),
@ -35,36 +36,66 @@
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsXPCOMGlue_h__
#define nsXPCOMGlue_h__
#include "nscore.h"
class nsILocalFile;
/**
* The following function is available in both the standalone and
* dynamically linked versions of the glue.
*/
/**
* Locate the path of a particular version of the GRE.
*
* @param version The GRE version to search for.
* @param buffer A buffer to be filled with the appropriate path. If the
* "local" GRE is specified (via the USE_LOCAL_GRE environment
* variable, for example), this buffer will be set to the empty
* string.
* @param buflen The length of buffer. This must be at least
* PATH_MAX/MAXPATHLEN.
* @throws NS_ERROR_FAILURE if an appropriate GRE could not be found.
*/
extern "C" NS_COM_GLUE nsresult
GRE_GetGREPathForVersion(const char *version,
char *buffer, PRUint32 buflen);
#ifdef XPCOM_GLUE
/**
* The following functions are only available in the standalone glue.
*/
/**
* Initialize the XPCOM glue by dynamically linking against the XPCOM
* shared library indicated by xpcomFile.
*/
extern "C"
nsresult XPCOMGlueStartup(const char* xpcomFile);
extern "C" NS_HIDDEN_(nsresult)
XPCOMGlueStartup(const char* xpcomFile);
/**
* Finish the XPCOM glue after it is no longer needed.
*/
extern "C"
nsresult XPCOMGlueShutdown();
extern "C" NS_HIDDEN_(nsresult)
XPCOMGlueShutdown();
/**
* Locate the path of a compatible GRE.
* Locate the path of a compatible GRE. This looks for the GRE version in
* nsBuildID.h, which is generated at build time. Unless you set
* MOZ_MILESTONE_RELEASE this will probably not be a useful GRE version string.
*
* @return string buffer pointing to the GRE path (without a trailing
* directory separator). Callers do no need to free this buffer.
* directory separator). Callers do not need to free this buffer.
*/
extern "C"
char const * GRE_GetGREPath();
extern "C" NS_HIDDEN_(char const *)
GRE_GetGREPath();
/**
@ -73,9 +104,8 @@ char const * GRE_GetGREPath();
*
* @param _retval Ordinary XPCOM getter, returns an addrefed interface.
*/
extern "C"
nsresult GRE_GetGREDirectory(nsILocalFile* *_retval);
extern "C" NS_HIDDEN_(nsresult)
GRE_GetGREDirectory(nsILocalFile* *_retval);
/**
@ -86,9 +116,8 @@ nsresult GRE_GetGREDirectory(nsILocalFile* *_retval);
* @return string buffer pointing to the XPCOM DLL path. Callers do
* not need to free this buffer.
*/
extern "C"
char const * GRE_GetXPCOMPath();
extern "C" NS_HIDDEN_(char const *)
GRE_GetXPCOMPath();
/**
@ -96,14 +125,15 @@ char const * GRE_GetXPCOMPath();
* directoryserviceprovider may use GRE_Startup to start the XPCOM
* glue and initialize the GRE in one step.
*/
extern "C"
nsresult GRE_Startup();
extern "C" NS_HIDDEN_(nsresult)
GRE_Startup();
/**
* Shut down XPCOM and the XPCOM glue in one step.
*/
extern "C" NS_HIDDEN_(nsresult)
GRE_Shutdown();
extern "C"
nsresult GRE_Shutdown();
#endif // XPCOM_GLUE
#endif // nsXPCOMGlue_h__

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

@ -66,12 +66,19 @@ DEFINES += -DXULRUNNER_PROGNAME=\"xulrunner\"
REQUIRES = \
xpcom \
string \
appshell \
xulapp \
$(NULL)
CPPSRCS = nsXULRunnerApp.cpp
ifeq ($(OS_ARCH),WINNT)
CPPSRCS += nsRegisterGREWin.cpp
else
CPPSRCS += nsRegisterGREVoid.cpp
endif
ifdef MOZ_ENABLE_LIBXUL
CPPSRCS += nsINIParser.cpp
endif

53
xulrunner/app/nsRegisterGRE.h Executable file
Просмотреть файл

@ -0,0 +1,53 @@
/* ***** 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 XULRunner.
*
* The Initial Developer of the Original Code is
* Benjamin Smedberg <benjamin@smedbergs.us>.
*
* Portions created by the Initial Developer are Copyright (C) 2005
* 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 ***** */
#ifndef nsRegisterGRE_h__
#define nsRegisterGRE_h__
#include "nscore.h"
class nsIFile;
/**
* @return PR_TRUE on success
*/
NS_HIDDEN_(PRBool)
RegisterXULRunner(PRBool aRegisterGlobally, nsIFile* aLocation);
NS_HIDDEN_(void)
UnregisterXULRunner(PRBool aUnregisterGlobally, nsIFile* aLocation);
#endif // nsRegisterGRE_h__

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

@ -0,0 +1,54 @@
/* ***** 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 XULRunner.
*
* The Initial Developer of the Original Code is
* Benjamin Smedberg <benjamin@smedbergs.us>.
*
* Portions created by the Initial Developer are Copyright (C) 2005
* 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 ***** */
#include "nsRegisterGRE.h"
#include <stdlib.h>
#include <stdio.h>
int
RegisterXULRunner(PRBool aRegisterGlobally, nsIFile* aLocation)
{
fprintf(stderr, "Registration not implemented on this platform!\n");
return 1;
}
void
UnregisterXULRunner(PRBool aUnregisterGlobally, nsIFile* aLocation)
{
fprintf(stderr, "Registration not implemented on this platform!\n");
}

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

@ -0,0 +1,255 @@
/* ***** 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 XULRunner.
*
* The Initial Developer of the Original Code is
* Benjamin Smedberg <benjamin@smedbergs.us>.
*
* Portions created by the Initial Developer are Copyright (C) 2005
* 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 ***** */
#include "nsRegisterGRE.h"
#include "nsIFile.h"
#include "nsILocalFile.h"
#include "nsBuildID.h"
#include "nsAppRunner.h" // for MAXPATHLEN
#include "nsString.h"
#include "prio.h"
#include <windows.h>
static const char kRegKeyRoot[] = "Software\\mozilla.org\\GRE";
static const char kRegFileGlobal[] = "global.reginfo";
static const char kRegFileUser[] = "user.reginfo";
static nsresult
MakeVersionKey(HKEY root, const char* keyname, const nsCAutoString &grehome)
{
HKEY subkey;
DWORD disp;
if (::RegCreateKeyEx(root, keyname, NULL, NULL, 0, KEY_WRITE, NULL,
&subkey, &disp) != ERROR_SUCCESS)
return NS_ERROR_FAILURE;
if (disp != REG_CREATED_NEW_KEY) {
::RegCloseKey(subkey);
return NS_ERROR_FAILURE;
}
if (::RegSetValueEx(subkey, "Version", NULL, REG_SZ, (BYTE*) GRE_BUILD_ID,
sizeof(GRE_BUILD_ID) - 1) == ERROR_SUCCESS &&
::RegSetValueEx(subkey, "GreHome", NULL, REG_SZ, (BYTE*) grehome.get(),
grehome.Length()) == ERROR_SUCCESS) {
::RegCloseKey(subkey);
return NS_OK;
}
// we created a key but couldn't fill it properly: delete it
::RegCloseKey(subkey);
::RegDeleteKey(root, keyname);
return NS_ERROR_FAILURE;
}
int
RegisterXULRunner(PRBool aRegisterGlobally, nsIFile* aLocation)
{
// Register ourself in the windows registry, and record what key we created
// for future unregistration.
nsresult rv;
PRBool irv;
nsCAutoString greHome;
rv = aLocation->GetNativePath(greHome);
if (NS_FAILED(rv))
return rv;
nsCOMPtr<nsIFile> savedInfoFile;
aLocation->Clone(getter_AddRefs(savedInfoFile));
nsCOMPtr<nsILocalFile> localSaved(do_QueryInterface(savedInfoFile));
if (!localSaved)
return PR_FALSE;
const char *infoname = aRegisterGlobally ? kRegFileGlobal : kRegFileUser;
localSaved->AppendNative(nsDependentCString(infoname));
PRFileDesc* fd = nsnull;
rv = localSaved->OpenNSPRFileDesc(PR_CREATE_FILE | PR_RDWR, 0664, &fd);
if (NS_FAILED(rv)) {
// XXX report error?
return PR_FALSE;
}
HKEY rootKey = NULL;
if (::RegCreateKeyEx(aRegisterGlobally ? HKEY_LOCAL_MACHINE :
HKEY_CURRENT_USER,
kRegKeyRoot, NULL, NULL, 0, KEY_WRITE,
NULL, &rootKey, NULL) != ERROR_SUCCESS) {
irv = PR_FALSE;
goto reg_end;
}
char keyName[MAXPATHLEN];
PRInt32 r = PR_Read(fd, keyName, MAXPATHLEN);
if (r < 0) {
irv = PR_FALSE;
goto reg_end;
}
if (r > 0) {
keyName[r] = '\0';
// There was already a .reginfo file, let's see if we are already
// registered.
HKEY existing = NULL;
if (::RegOpenKeyEx(rootKey, keyName, NULL, KEY_QUERY_VALUE, &existing) ==
ERROR_SUCCESS) {
fprintf(stderr, "Warning: Registry key Software\\mozilla.org\\GRE\\%s already exists.\n"
"No action was performed.\n",
keyName);
irv = PR_FALSE;
goto reg_end;
}
PR_Close(fd);
fd = nsnull;
rv = localSaved->OpenNSPRFileDesc(PR_CREATE_FILE | PR_WRONLY | PR_TRUNCATE, 0664, &fd);
if (NS_FAILED(rv)) {
// XXX report error?
irv = PR_FALSE;
goto reg_end;
}
}
strcpy(keyName, GRE_BUILD_ID);
rv = MakeVersionKey(rootKey, keyName, greHome);
if (NS_SUCCEEDED(rv)) {
PR_Write(fd, keyName, strlen(keyName));
irv = PR_TRUE;
goto reg_end;
}
for (int i = 0; i < 1000; ++i) {
sprintf(keyName, GRE_BUILD_ID "_%i", i);
rv = MakeVersionKey(rootKey, keyName, greHome);
if (NS_SUCCEEDED(rv)) {
PR_Write(fd, keyName, strlen(keyName));
irv = PR_FALSE;
goto reg_end;
}
}
irv = PR_FALSE;
reg_end:
if (fd)
PR_Close(fd);
if (rootKey)
::RegCloseKey(rootKey);
return irv;
}
void
UnregisterXULRunner(PRBool aGlobal, nsIFile* aLocation)
{
nsCOMPtr<nsIFile> savedInfoFile;
aLocation->Clone(getter_AddRefs(savedInfoFile));
nsCOMPtr<nsILocalFile> localSaved (do_QueryInterface(savedInfoFile));
if (!localSaved)
return;
const char *infoname = aGlobal ? kRegFileGlobal : kRegFileUser;
localSaved->AppendNative(nsDependentCString(infoname));
PRFileDesc* fd = nsnull;
nsresult rv = localSaved->OpenNSPRFileDesc(PR_RDONLY, 0, &fd);
if (NS_FAILED(rv)) {
// XXX report error?
return;
}
char keyName[MAXPATHLEN];
PRInt32 r = PR_Read(fd, keyName, MAXPATHLEN);
PR_Close(fd);
localSaved->Remove(PR_FALSE);
if (r <= 0)
return;
keyName[r] = '\0';
HKEY rootKey = NULL;
if (::RegOpenKeyEx(aGlobal ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER,
kRegKeyRoot, 0, KEY_READ, &rootKey) != ERROR_SUCCESS)
return;
HKEY subKey = NULL;
if (::RegOpenKeyEx(rootKey, keyName, 0, KEY_READ, &subKey) == ERROR_SUCCESS) {
char regpath[MAXPATHLEN];
DWORD reglen = MAXPATHLEN;
if (::RegQueryValueEx(subKey, "GreHome", NULL, NULL,
(BYTE*) regpath, &reglen) == ERROR_SUCCESS) {
nsCOMPtr<nsILocalFile> regpathfile;
rv = NS_NewNativeLocalFile(nsDependentCString(regpath), PR_FALSE,
getter_AddRefs(regpathfile));
PRBool eq;
if (NS_SUCCEEDED(rv) &&
NS_SUCCEEDED(aLocation->Equals(regpathfile, &eq)) && !eq) {
// We think we registered for this key, but it doesn't point to
// us any more!
fprintf(stderr, "Warning: Registry key Software\\mozilla.org\\GRE\\%s points to\n"
"alternate path '%s'; unregistration was not successful.\n",
keyName, regpath);
::RegCloseKey(subKey);
::RegCloseKey(rootKey);
return;
}
}
::RegCloseKey(subKey);
}
::RegDeleteKey(rootKey, keyName);
::RegCloseKey(rootKey);
}

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

@ -42,6 +42,8 @@
#endif
#include "nsXULAppAPI.h"
#include "nsXPCOMGlue.h"
#include "nsRegisterGRE.h"
#include "nsAppRunner.h"
#include "nsINIParser.h"
#include "nsILocalFile.h"
@ -205,7 +207,7 @@ static int LoadAppData(const char* appDataFile, nsXREAppData* aResult)
}
else if (string_fields[i].required) {
Output(PR_TRUE, "Error: %x: No \"%s\" field.\n",
rv, string_fields[i].key);
rv, string_fields[i].key);
return 1;
}
}
@ -249,21 +251,49 @@ static void Usage()
{
// display additional information (XXX make localizable?)
Output(PR_FALSE,
"Mozilla XULRunner " MOZILLA_VERSION " %d\n\n"
"Usage: " XULRUNNER_PROGNAME
" [OPTIONS] [APP-FILE [APP-OPTIONS...]]\n"
"Mozilla XULRunner %s\n\n"
"Usage: " XULRUNNER_PROGNAME "[OPTIONS]\n"
" " XULRUNNER_PROGNAME "APP-FILE [APP-OPTIONS...]\n"
"\n"
"OPTIONS\n"
" --app specify APP-FILE (optional)\n"
" -h, --help show this message\n"
" -v, --version show version\n"
" --app specify APP-FILE (optional)\n"
" -h, --help show this message\n"
" -v, --version show version\n"
" --gre-version print the GRE version string on stdout"
" --register-global register this GRE in the machine registry.\n"
" --register-user register this GRE in the user registry\n"
" --unregister-global unregister this GRE formerly registered with\n"
" --register-global\n"
" --unregister-user unregister this GRE formely registered with\n"
" --register-user\n"
" --find-gre <version> Find a GRE with version <version> and print\n"
" the path on stdout\n"
"\n"
"APP-FILE\n"
" Application initialization file.\n"
"\n"
"APP-OPTIONS\n"
" Application specific options.\n",
BUILD_ID);
GRE_BUILD_ID);
}
static nsresult
GetXULRunnerDir(const char *argv0, nsIFile* *aResult)
{
nsresult rv;
nsCOMPtr<nsILocalFile> appFile;
rv = XRE_GetBinaryPath(argv0, getter_AddRefs(appFile));
if (NS_FAILED(rv)) {
Output(PR_TRUE, "Could not find XULRunner application path.\n");
return rv;
}
rv = appFile->GetParent(aResult);
if (NS_FAILED(rv)) {
Output(PR_TRUE, "Could not find XULRunner installation dir.\n");
}
return rv;
}
int main(int argc, char* argv[])
@ -278,8 +308,64 @@ int main(int argc, char* argv[])
if (argc == 2 && (IsArg(argv[1], "v") || IsArg(argv[1], "version")))
{
Output(PR_FALSE, "Mozilla XULRunner " MOZILLA_VERSION " %d\n",
BUILD_ID);
Output(PR_FALSE, "Mozilla XULRunner %s\n", GRE_BUILD_ID);
return 0;
}
PRBool registerGlobal = IsArg(argv[1], "register-global");
PRBool registerUser = IsArg(argv[1], "register-user");
if (registerGlobal || registerUser) {
if (argc != 2) {
Usage();
return 1;
}
nsCOMPtr<nsIFile> regDir;
nsresult rv = GetXULRunnerDir(argv[0], getter_AddRefs(regDir));
if (NS_FAILED(rv))
return 2;
return RegisterXULRunner(registerGlobal, regDir) ? 0 : 2;
}
registerGlobal = IsArg(argv[1], "unregister-global");
registerUser = IsArg(argv[1], "unregister-user");
if (IsArg(argv[1], "unregister-global")) {
if (argc != 2) {
Usage();
return 1;
}
nsCOMPtr<nsIFile> regDir;
nsresult rv = GetXULRunnerDir(argv[0], getter_AddRefs(regDir));
if (NS_FAILED(rv))
return 2;
UnregisterXULRunner(registerGlobal, regDir);
return 0;
}
if (IsArg(argv[1], "find-gre")) {
if (argc != 3) {
Usage();
return 1;
}
char version[MAXPATHLEN];
nsresult rv = GRE_GetGREPathForVersion(argv[2], version, MAXPATHLEN);
if (NS_FAILED(rv))
return 1;
printf("%s\n", version);
return 0;
}
if (IsArg(argv[1], "gre-version")) {
if (argc != 2) {
Usage();
return 1;
}
printf("%s\n", GRE_BUILD_ID);
return 0;
}