Landing of interdependent bugs for Vista support. Bug 354005 Setting the app as the OS default is broken on Vista. r=sspitzer, r=dougt, sr=bsmedberg. Bug 351949 Automatic Update is not working for Vista users with limited account privilege and UAC (User Account Control) enabled. r=sspitzer, r=rstrong. Bug 354226 nsPostUpdateWin.js fails to update registry keys / log files after an update has been applied. r=rstrong.
git-svn-id: svn://10.0.0.236/trunk@219158 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -61,6 +61,8 @@ const nsIWindowWatcher = Components.interfaces.nsIWindowWatcher;
|
||||
const nsICategoryManager = Components.interfaces.nsICategoryManager;
|
||||
const nsIWebNavigationInfo = Components.interfaces.nsIWebNavigationInfo;
|
||||
const nsIBrowserSearchService = Components.interfaces.nsIBrowserSearchService;
|
||||
const nsITimer = Components.interfaces.nsITimer;
|
||||
const nsITimerCallback = Components.interfaces.nsITimerCallback;
|
||||
|
||||
const NS_BINDING_ABORTED = 0x804b0002;
|
||||
const NS_ERROR_WONT_HANDLE_CONTENT = 0x805d0001;
|
||||
@@ -595,16 +597,73 @@ var nsDefaultCommandLineHandler = {
|
||||
QueryInterface : function dch_QI(iid) {
|
||||
if (!iid.equals(nsISupports) &&
|
||||
!iid.equals(nsICommandLineHandler) &&
|
||||
!iid.equals(nsITimerCallback) &&
|
||||
!iid.equals(nsIFactory))
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
// True when a DDE request will follow
|
||||
_requestPending: false,
|
||||
_URIs: [ ],
|
||||
_timer: null,
|
||||
|
||||
/* nsITimerCallback - opens urls after the ui is sufficiently initialized */
|
||||
notify: function (aTimer) {
|
||||
try {
|
||||
var navWin = getMostRecentBrowserWindow();
|
||||
var navNav = navWin.QueryInterface(nsIInterfaceRequestor)
|
||||
.getInterface(nsIWebNavigation);
|
||||
var rootItem = navNav.QueryInterface(nsIDocShellTreeItem).rootTreeItem;
|
||||
var rootWin = rootItem.QueryInterface(nsIInterfaceRequestor)
|
||||
.getInterface(nsIDOMWindow);
|
||||
var bwin = rootWin.QueryInterface(nsIDOMChromeWindow).browserDOMWindow;
|
||||
if (bwin) {
|
||||
var browser = navWin.getBrowser();
|
||||
var tabPanels = browser.browsers;
|
||||
var count = this._URIs.length;
|
||||
for (var i = 0; i < count; ++i) {
|
||||
var uri = this._URIs[0];
|
||||
if (tabPanels.length == 1 &&
|
||||
tabPanels[0].currentURI.spec == "about:blank" &&
|
||||
!tabPanels[0].webProgress.isLoadingDocument) {
|
||||
if (shouldLoadURI(uri))
|
||||
handURIToExistingBrowser(uri, nsIBrowserDOMWindow.OPEN_CURRENTWINDOW);
|
||||
}
|
||||
else {
|
||||
handURIToExistingBrowser(uri, nsIBrowserDOMWindow.OPEN_DEFAULTWINDOW);
|
||||
}
|
||||
this._URIs.splice(0, 1);
|
||||
}
|
||||
this._requestPending = false;
|
||||
this._timer.cancel();
|
||||
this._timer = null;
|
||||
this._URIs = [ ];
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
}
|
||||
},
|
||||
|
||||
/* nsICommandLineHandler */
|
||||
handle : function dch_handle(cmdLine) {
|
||||
var urilist = [];
|
||||
|
||||
#ifdef XP_WIN
|
||||
if (cmdLine.handleFlag("requestpending", false) &&
|
||||
cmdLine.state == nsICommandLine.STATE_INITIAL_LAUNCH) {
|
||||
this._requestPending = true;
|
||||
// When the requestpending flag is present a dde message will follow that
|
||||
// contains the same url. By handling the url flag here as a noop
|
||||
// duplicate requests to open the same url are prevented. When the
|
||||
// application needs to restart during startup the requestpending flag
|
||||
// is removed and the url flag will be handled normally after the restart.
|
||||
cmdLine.handleFlagWithParam("url", false);
|
||||
}
|
||||
#endif
|
||||
|
||||
try {
|
||||
var ar;
|
||||
while ((ar = cmdLine.handleFlagWithParam("url", false))) {
|
||||
@@ -615,6 +674,41 @@ var nsDefaultCommandLineHandler = {
|
||||
Components.utils.reportError(e);
|
||||
}
|
||||
|
||||
#ifdef XP_WIN
|
||||
if (cmdLine.state == nsICommandLine.STATE_REMOTE_EXPLICIT && this._requestPending) {
|
||||
// Handdle DDE request to open an url by first trying to open it via an
|
||||
// existing window's openURI. If this fails a timer will be used to allow
|
||||
// the window to finish opening so the url can be opened correctly and
|
||||
// respect the OPEN_EXTERNAL pref.
|
||||
try {
|
||||
var navWin = getMostRecentBrowserWindow();
|
||||
var navNav = navWin.QueryInterface(nsIInterfaceRequestor)
|
||||
.getInterface(nsIWebNavigation);
|
||||
var rootItem = navNav.QueryInterface(nsIDocShellTreeItem).rootTreeItem;
|
||||
var rootWin = rootItem.QueryInterface(nsIInterfaceRequestor)
|
||||
.getInterface(nsIDOMWindow);
|
||||
var bwin = rootWin.QueryInterface(nsIDOMChromeWindow).browserDOMWindow;
|
||||
bwin.openURI(urilist[0], null, nsIBrowserDOMWindow.OPEN_DEFAULTWINDOW,
|
||||
nsIBrowserDOMWindow.OPEN_EXTERNAL);
|
||||
this._requestPending = false;
|
||||
}
|
||||
catch (e) {
|
||||
this._URIs.push(urilist[0]);
|
||||
// If multiple urls (e.g. local files, etc.) are opened at the same
|
||||
// time when the app is not running it is possible to have multiple
|
||||
// requests before there is a window available to handle the request so
|
||||
// a timer is used to allow the window to finish opening before
|
||||
// attempting to open the url.
|
||||
if (!this._timer) {
|
||||
this._timer = Components.classes["@mozilla.org/timer;1"]
|
||||
.createInstance(nsITimer);
|
||||
this._timer.initWithCallback(this, 100, nsITimer.TYPE_REPEATING_SLACK);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
var count = cmdLine.length;
|
||||
|
||||
for (var i = 0; i < count; ++i) {
|
||||
|
||||
@@ -62,6 +62,9 @@
|
||||
#include "shlobj.h"
|
||||
#include "nsIWindowsRegKey.h"
|
||||
|
||||
#include "windows.h"
|
||||
#include "shellapi.h"
|
||||
|
||||
#include <mbstring.h>
|
||||
|
||||
#ifndef MAX_BUF
|
||||
@@ -97,26 +100,40 @@ OpenUserKeyForReading(HKEY aStartKey, const char* aKeyName, HKEY* aKey)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Sets the default browser registry keys for Windows versions prior to Vista.
|
||||
// Try to open / create the key in HKLM and if that fails try to do the same
|
||||
// in HKCU. Though this is not strictly the behavior I would expect it is the
|
||||
// same behavior that IE has when setting the default browser previous to Vista.
|
||||
static nsresult
|
||||
OpenKeyForWriting(const char* aKeyName, HKEY* aKey, PRBool aForAllUsers, PRBool aCreate)
|
||||
OpenKeyForWriting(HKEY aStartKey, const char* aKeyName, HKEY* aKey,
|
||||
PRBool aHKLMOnly)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
DWORD dwDisp = 0;
|
||||
DWORD rv = ::RegCreateKeyEx(aStartKey, aKeyName, 0, NULL, 0,
|
||||
KEY_READ | KEY_WRITE, NULL, aKey, &dwDisp);
|
||||
|
||||
HKEY rootKey = aForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
|
||||
DWORD result = ::RegOpenKeyEx(rootKey, aKeyName, 0, KEY_READ | KEY_WRITE, aKey);
|
||||
|
||||
switch (result) {
|
||||
switch (rv) {
|
||||
case ERROR_SUCCESS:
|
||||
break;
|
||||
case ERROR_ACCESS_DENIED:
|
||||
return NS_ERROR_FILE_ACCESS_DENIED;
|
||||
if (aHKLMOnly || aStartKey == HKEY_CURRENT_USER)
|
||||
return NS_ERROR_FILE_ACCESS_DENIED;
|
||||
// fallback to HKCU immediately on access denied since we won't be able
|
||||
// to create the key.
|
||||
return OpenKeyForWriting(HKEY_CURRENT_USER, aKeyName, aKey, aHKLMOnly);
|
||||
case ERROR_FILE_NOT_FOUND:
|
||||
if (aCreate)
|
||||
result = ::RegCreateKey(HKEY_LOCAL_MACHINE, aKeyName, aKey);
|
||||
rv = NS_ERROR_FILE_NOT_FOUND;
|
||||
break;
|
||||
rv = ::RegCreateKey(aStartKey, aKeyName, aKey);
|
||||
if (rv != ERROR_SUCCESS) {
|
||||
if (aHKLMOnly || aStartKey == HKEY_CURRENT_USER) {
|
||||
// prevent infinite recursion on the second pass through here if
|
||||
// ::RegCreateKey fails in the current user case.
|
||||
return NS_ERROR_FILE_ACCESS_DENIED;
|
||||
}
|
||||
return OpenKeyForWriting(HKEY_CURRENT_USER, aKeyName, aKey, aHKLMOnly);
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@@ -128,55 +145,69 @@ OpenKeyForWriting(const char* aKeyName, HKEY* aKey, PRBool aForAllUsers, PRBool
|
||||
// .htm .html .shtml .xht .xhtml
|
||||
// are mapped like so:
|
||||
//
|
||||
// HKCU\SOFTWARE\Classes\.<ext>\ (default) REG_SZ FirefoxHTML
|
||||
// HKCU\SOFTWARE\Classes\.<ext>\ (default) REG_SZ FirefoxHTML
|
||||
//
|
||||
// as aliases to the class:
|
||||
//
|
||||
// HKCU\SOFTWARE\Classes\FirefoxHTML\
|
||||
// DefaultIcon (default) REG_SZ <appname>,1
|
||||
// shell\open\command (default) REG_SZ <appname> -url "%1"
|
||||
// DefaultIcon (default) REG_SZ <apppath>,1
|
||||
// shell\open\command (default) REG_SZ <apppath> -url "%1" -requestPending
|
||||
// shell\open\ddeexec (default) REG_SZ "%1",,0,0,,,,
|
||||
// shell\open\ddeexec NoActivateHandler REG_SZ
|
||||
// \Application (default) REG_SZ Firefox
|
||||
// \Topic (default) REG_SZ WWW_OpenURL
|
||||
//
|
||||
// - Windows Vista Protocol Handler
|
||||
//
|
||||
// HKCU\SOFTWARE\Classes\FirefoxURL\ (default) REG_SZ <appname> URL
|
||||
// EditFlags REG_DWORD 2
|
||||
// FriendlyTypeName REG_SZ <appname> URL
|
||||
// DefaultIcon (default) REG_SZ <apppath>,0
|
||||
// shell\open\command (default) REG_SZ <apppath> -url "%1" -requestPending
|
||||
// shell\open\ddeexec (default) REG_SZ "%1",,0,0,,,,
|
||||
// shell\open\ddeexec NoActivateHandler REG_SZ
|
||||
// \Application (default) REG_SZ Firefox
|
||||
// \Topic (default) REG_SZ WWW_OpenURL
|
||||
//
|
||||
// - Protocol Mappings
|
||||
// -----------------
|
||||
// The following protocols:
|
||||
// HTTP, HTTPS, FTP, GOPHER, CHROME
|
||||
// HTTP, HTTPS, FTP, GOPHER
|
||||
// are mapped like so:
|
||||
//
|
||||
// HKCU\SOFTWARE\Classes\<protocol>\
|
||||
// DefaultIcon (default) REG_SZ <appname>,0
|
||||
// shell\open\command (default) REG_SZ <appname> -url "%1"
|
||||
// shell\open\ddeexec (default) REG_SZ "%1",,0,0,,,,
|
||||
// shell\open\ddeexec NoActivateHandler REG_SZ
|
||||
// \application (default) REG_SZ Firefox
|
||||
// \ifexec (default) REG_SZ ,,0,0,,,,
|
||||
// \topic (default) REG_SZ WWW_OpenURL
|
||||
//
|
||||
// HKCU\SOFTWARE\Classes\<protocol>\
|
||||
// DefaultIcon (default) REG_SZ <apppath>,0
|
||||
// shell\open\command (default) REG_SZ <apppath> -url "%1" -requestPending
|
||||
// shell\open\ddeexec (default) REG_SZ "%1",,0,0,,,,
|
||||
// shell\open\ddeexec NoActivateHandler REG_SZ
|
||||
// \Application (default) REG_SZ Firefox
|
||||
// \Topic (default) REG_SZ WWW_OpenURL
|
||||
//
|
||||
// - Windows XP Start Menu Browser
|
||||
// -----------------------------
|
||||
// The following keys are set to make Firefox appear in the Windows XP
|
||||
// Start Menu as the browser:
|
||||
// - Windows Start Menu (Win2K SP2, XP SP1, and newer)
|
||||
// -------------------------------------------------
|
||||
// The following keys are set to make Firefox appear in the Start Menu as the
|
||||
// browser:
|
||||
//
|
||||
// HKCU\SOFTWARE\Clients\StartMenuInternet
|
||||
// firefox.exe\DefaultIcon (default) REG_SZ <appname>,0
|
||||
// firefox.exe\shell\open\command (default) REG_SZ <appname>
|
||||
// firefox.exe\shell\properties (default) REG_SZ Firefox &Options
|
||||
// firefox.exe\shell\properties\command(default) REG_SZ <appname> -preferences
|
||||
//
|
||||
// - Uninstall Information
|
||||
// ---------------------
|
||||
// Every key that is set has the previous value stored in:
|
||||
//
|
||||
// HKCU\SOFTWARE\Mozilla\Desktop\ <keyname> REG_SZ oldval
|
||||
//
|
||||
// If there is no previous value, an empty value is set to indicate that the
|
||||
// key should be removed completely.
|
||||
// HKCU\SOFTWARE\Clients\StartMenuInternet\FIREFOX.EXE\
|
||||
// (default) REG_SZ <appname>
|
||||
// DefaultIcon (default) REG_SZ <apppath>,0
|
||||
// InstallInfo HideIconsCommand REG_SZ <uninstpath> /HideShortcuts
|
||||
// InstallInfo IconsVisible REG_DWORD 1
|
||||
// InstallInfo ReinstallCommand REG_SZ <uninstpath> /SetAsDefaultAppGlobal
|
||||
// InstallInfo ShowIconsCommand REG_SZ <uninstpath> /ShowShortcuts
|
||||
// shell\open\command (default) REG_SZ <apppath>
|
||||
// shell\properties (default) REG_SZ <appname> &Options
|
||||
// shell\properties\command (default) REG_SZ <apppath> -preferences
|
||||
// shell\safemode (default) REG_SZ <appname> &Safe Mode
|
||||
// shell\safemode\command (default) REG_SZ <apppath> -safe-mode
|
||||
//
|
||||
|
||||
typedef enum { NO_SUBSTITUTION = 0x00,
|
||||
PATH_SUBSTITUTION = 0x01,
|
||||
EXE_SUBSTITUTION = 0x02,
|
||||
NON_ESSENTIAL = 0x04} SettingFlags;
|
||||
typedef enum { NO_SUBSTITUTION = 0x00,
|
||||
APP_PATH_SUBSTITUTION = 0x01,
|
||||
EXE_NAME_SUBSTITUTION = 0x02,
|
||||
UNINST_PATH_SUBSTITUTION = 0x04,
|
||||
HKLM_ONLY = 0x08,
|
||||
NON_ESSENTIAL = 0x10 } SettingFlags;
|
||||
typedef struct {
|
||||
char* keyName;
|
||||
char* valueName;
|
||||
@@ -185,20 +216,24 @@ typedef struct {
|
||||
PRInt32 flags;
|
||||
} SETTING;
|
||||
|
||||
#define APP_REG_NAME L"Firefox"
|
||||
#define SMI "SOFTWARE\\Clients\\StartMenuInternet\\"
|
||||
#define CLS "SOFTWARE\\Classes\\"
|
||||
#define DI "\\DefaultIcon"
|
||||
#define II "\\InstallInfo"
|
||||
#define SOP "\\shell\\open\\command"
|
||||
#define DDE "\\shell\\open\\ddeexec\\"
|
||||
#define DDE_NAME "Firefox" // This must be kept in sync with ID_DDE_APPLICATION_NAME as defined in splash.rc
|
||||
#define APP_REG_NAME L"Firefox"
|
||||
#define DDE_COMMAND "\"%1\",,0,0,,,,"
|
||||
#define DDE_IFEXEC ",,0,0,,,,"
|
||||
// For the InstallInfo HideIconsCommand, ShowIconsCommand, and ReinstallCommand
|
||||
// registry keys. This must be kept in sync with the uninstaller.
|
||||
#define UNINSTALL_EXE "\\uninstall\\helper.exe"
|
||||
|
||||
#define CLS_HTML "FirefoxHTML"
|
||||
#define CLS_URL "FirefoxURL"
|
||||
#define VAL_URL_ICON "%APPPATH%,0"
|
||||
#define VAL_FILE_ICON "%APPPATH%,1"
|
||||
#define VAL_OPEN "\"%APPPATH%\" -url \"%1\""
|
||||
#define VAL_OPEN "\"%APPPATH%\" -url \"%1\" -requestPending"
|
||||
|
||||
#define MAKE_KEY_NAME1(PREFIX, MID) \
|
||||
PREFIX MID
|
||||
@@ -210,12 +245,6 @@ typedef struct {
|
||||
PREFIX MID MID2 SUFFIX
|
||||
|
||||
static SETTING gSettings[] = {
|
||||
// Extension Manager Keys
|
||||
{ MAKE_KEY_NAME1(CLS, "MIME\\Database\\Content Type\\application/x-xpinstall;app=firefox"),
|
||||
"Extension",
|
||||
".xpi",
|
||||
NO_SUBSTITUTION | NON_ESSENTIAL },
|
||||
|
||||
// File Extension Aliases
|
||||
{ MAKE_KEY_NAME1(CLS, ".htm"), "", CLS_HTML, NO_SUBSTITUTION | NON_ESSENTIAL },
|
||||
{ MAKE_KEY_NAME1(CLS, ".html"), "", CLS_HTML, NO_SUBSTITUTION | NON_ESSENTIAL },
|
||||
@@ -224,64 +253,72 @@ static SETTING gSettings[] = {
|
||||
{ MAKE_KEY_NAME1(CLS, ".xhtml"), "", CLS_HTML, NO_SUBSTITUTION | NON_ESSENTIAL },
|
||||
|
||||
// File Extension Class
|
||||
{ MAKE_KEY_NAME2(CLS, CLS_HTML, DI), "", VAL_FILE_ICON, PATH_SUBSTITUTION | NON_ESSENTIAL },
|
||||
{ MAKE_KEY_NAME2(CLS, CLS_HTML, SOP), "", VAL_OPEN, PATH_SUBSTITUTION | NON_ESSENTIAL },
|
||||
{ MAKE_KEY_NAME2(CLS, CLS_HTML, DI), "", VAL_FILE_ICON, APP_PATH_SUBSTITUTION },
|
||||
{ MAKE_KEY_NAME2(CLS, CLS_HTML, SOP), "", VAL_OPEN, APP_PATH_SUBSTITUTION },
|
||||
|
||||
// Protocol Handler Class - for Vista and above
|
||||
{ MAKE_KEY_NAME2(CLS, CLS_URL, DI), "", VAL_URL_ICON, APP_PATH_SUBSTITUTION },
|
||||
{ MAKE_KEY_NAME2(CLS, CLS_URL, SOP), "", VAL_OPEN, APP_PATH_SUBSTITUTION },
|
||||
|
||||
// Protocol Handlers
|
||||
{ MAKE_KEY_NAME2(CLS, "HTTP", DI), "", VAL_URL_ICON, PATH_SUBSTITUTION },
|
||||
{ MAKE_KEY_NAME2(CLS, "HTTP", SOP), "", VAL_OPEN, PATH_SUBSTITUTION },
|
||||
{ MAKE_KEY_NAME2(CLS, "HTTPS", DI), "", VAL_URL_ICON, PATH_SUBSTITUTION },
|
||||
{ MAKE_KEY_NAME2(CLS, "HTTPS", SOP), "", VAL_OPEN, PATH_SUBSTITUTION },
|
||||
{ MAKE_KEY_NAME2(CLS, "FTP", DI), "", VAL_URL_ICON, PATH_SUBSTITUTION | NON_ESSENTIAL },
|
||||
{ MAKE_KEY_NAME2(CLS, "FTP", SOP), "", VAL_OPEN, PATH_SUBSTITUTION | NON_ESSENTIAL },
|
||||
{ MAKE_KEY_NAME2(CLS, "GOPHER", DI), "", VAL_URL_ICON, PATH_SUBSTITUTION | NON_ESSENTIAL },
|
||||
{ MAKE_KEY_NAME2(CLS, "GOPHER", SOP), "", VAL_OPEN, PATH_SUBSTITUTION | NON_ESSENTIAL },
|
||||
{ MAKE_KEY_NAME2(CLS, "CHROME", DI), "", VAL_URL_ICON, PATH_SUBSTITUTION | NON_ESSENTIAL },
|
||||
{ MAKE_KEY_NAME2(CLS, "CHROME", SOP), "", VAL_OPEN, PATH_SUBSTITUTION | NON_ESSENTIAL },
|
||||
{ MAKE_KEY_NAME2(CLS, "HTTP", DI), "", VAL_URL_ICON, APP_PATH_SUBSTITUTION },
|
||||
{ MAKE_KEY_NAME2(CLS, "HTTP", SOP), "", VAL_OPEN, APP_PATH_SUBSTITUTION },
|
||||
{ MAKE_KEY_NAME2(CLS, "HTTPS", DI), "", VAL_URL_ICON, APP_PATH_SUBSTITUTION },
|
||||
{ MAKE_KEY_NAME2(CLS, "HTTPS", SOP), "", VAL_OPEN, APP_PATH_SUBSTITUTION },
|
||||
{ MAKE_KEY_NAME2(CLS, "FTP", DI), "", VAL_URL_ICON, APP_PATH_SUBSTITUTION | NON_ESSENTIAL },
|
||||
{ MAKE_KEY_NAME2(CLS, "FTP", SOP), "", VAL_OPEN, APP_PATH_SUBSTITUTION | NON_ESSENTIAL },
|
||||
{ MAKE_KEY_NAME2(CLS, "GOPHER", DI), "", VAL_URL_ICON, APP_PATH_SUBSTITUTION | NON_ESSENTIAL },
|
||||
{ MAKE_KEY_NAME2(CLS, "GOPHER", SOP), "", VAL_OPEN, APP_PATH_SUBSTITUTION | NON_ESSENTIAL },
|
||||
|
||||
// DDE settings
|
||||
{ MAKE_KEY_NAME2(CLS, CLS_HTML, DDE), "", DDE_COMMAND, NO_SUBSTITUTION },
|
||||
{ MAKE_KEY_NAME3(CLS, CLS_HTML, DDE, "Application"), "", DDE_NAME, NO_SUBSTITUTION },
|
||||
{ MAKE_KEY_NAME3(CLS, CLS_HTML, DDE, "Topic"), "", "WWW_OpenURL", NO_SUBSTITUTION },
|
||||
{ MAKE_KEY_NAME3(CLS, CLS_HTML, DDE, "ifexec"), "", DDE_IFEXEC, NO_SUBSTITUTION },
|
||||
{ MAKE_KEY_NAME2(CLS, "HTTP", DDE), "", DDE_COMMAND, NO_SUBSTITUTION },
|
||||
{ MAKE_KEY_NAME3(CLS, "HTTP", DDE, "Application"), "", DDE_NAME, NO_SUBSTITUTION },
|
||||
{ MAKE_KEY_NAME3(CLS, "HTTP", DDE, "Topic"), "", "WWW_OpenURL", NO_SUBSTITUTION },
|
||||
{ MAKE_KEY_NAME3(CLS, "HTTP", DDE, "ifexec"), "", DDE_IFEXEC, NO_SUBSTITUTION },
|
||||
{ MAKE_KEY_NAME2(CLS, "HTTPS", DDE), "", DDE_COMMAND, NO_SUBSTITUTION },
|
||||
{ MAKE_KEY_NAME3(CLS, "HTTPS", DDE, "Application"), "", DDE_NAME, NO_SUBSTITUTION },
|
||||
{ MAKE_KEY_NAME3(CLS, "HTTPS", DDE, "Topic"), "", "WWW_OpenURL", NO_SUBSTITUTION },
|
||||
{ MAKE_KEY_NAME3(CLS, "HTTPS", DDE, "ifexec"), "", DDE_IFEXEC, NO_SUBSTITUTION },
|
||||
{ MAKE_KEY_NAME2(CLS, "FTP", DDE), "", DDE_COMMAND, NO_SUBSTITUTION },
|
||||
{ MAKE_KEY_NAME3(CLS, "FTP", DDE, "Application"), "", DDE_NAME, NO_SUBSTITUTION },
|
||||
{ MAKE_KEY_NAME3(CLS, "FTP", DDE, "Topic"), "", "WWW_OpenURL", NO_SUBSTITUTION },
|
||||
{ MAKE_KEY_NAME3(CLS, "FTP", DDE, "ifexec"), "", DDE_IFEXEC, NO_SUBSTITUTION },
|
||||
{ MAKE_KEY_NAME2(CLS, CLS_HTML, DDE), "", DDE_COMMAND, NO_SUBSTITUTION | NON_ESSENTIAL },
|
||||
{ MAKE_KEY_NAME3(CLS, CLS_HTML, DDE, "Application"), "", DDE_NAME, NO_SUBSTITUTION | NON_ESSENTIAL },
|
||||
{ MAKE_KEY_NAME3(CLS, CLS_HTML, DDE, "Topic"), "", "WWW_OpenURL", NO_SUBSTITUTION | NON_ESSENTIAL },
|
||||
{ MAKE_KEY_NAME2(CLS, CLS_URL, DDE), "", DDE_COMMAND, NO_SUBSTITUTION | NON_ESSENTIAL },
|
||||
{ MAKE_KEY_NAME3(CLS, CLS_URL, DDE, "Application"), "", DDE_NAME, NO_SUBSTITUTION | NON_ESSENTIAL },
|
||||
{ MAKE_KEY_NAME3(CLS, CLS_URL, DDE, "Topic"), "", "WWW_OpenURL", NO_SUBSTITUTION | NON_ESSENTIAL },
|
||||
{ MAKE_KEY_NAME2(CLS, "HTTP", DDE), "", DDE_COMMAND, NO_SUBSTITUTION | NON_ESSENTIAL },
|
||||
{ MAKE_KEY_NAME3(CLS, "HTTP", DDE, "Application"), "", DDE_NAME, NO_SUBSTITUTION | NON_ESSENTIAL },
|
||||
{ MAKE_KEY_NAME3(CLS, "HTTP", DDE, "Topic"), "", "WWW_OpenURL", NO_SUBSTITUTION | NON_ESSENTIAL },
|
||||
{ MAKE_KEY_NAME2(CLS, "HTTPS", DDE), "", DDE_COMMAND, NO_SUBSTITUTION | NON_ESSENTIAL },
|
||||
{ MAKE_KEY_NAME3(CLS, "HTTPS", DDE, "Application"), "", DDE_NAME, NO_SUBSTITUTION | NON_ESSENTIAL },
|
||||
{ MAKE_KEY_NAME3(CLS, "HTTPS", DDE, "Topic"), "", "WWW_OpenURL", NO_SUBSTITUTION | NON_ESSENTIAL },
|
||||
{ MAKE_KEY_NAME2(CLS, "FTP", DDE), "", DDE_COMMAND, NO_SUBSTITUTION | NON_ESSENTIAL },
|
||||
{ MAKE_KEY_NAME3(CLS, "FTP", DDE, "Application"), "", DDE_NAME, NO_SUBSTITUTION | NON_ESSENTIAL },
|
||||
{ MAKE_KEY_NAME3(CLS, "FTP", DDE, "Topic"), "", "WWW_OpenURL", NO_SUBSTITUTION | NON_ESSENTIAL },
|
||||
{ MAKE_KEY_NAME2(CLS, "GOPHER", DDE), "", DDE_COMMAND, NO_SUBSTITUTION | NON_ESSENTIAL },
|
||||
{ MAKE_KEY_NAME3(CLS, "GOPHER", DDE, "Application"), "", DDE_NAME, NO_SUBSTITUTION | NON_ESSENTIAL },
|
||||
{ MAKE_KEY_NAME3(CLS, "GOPHER", DDE, "Topic"), "", "WWW_OpenURL", NO_SUBSTITUTION | NON_ESSENTIAL },
|
||||
{ MAKE_KEY_NAME3(CLS, "GOPHER", DDE, "ifexec"), "", DDE_IFEXEC, NO_SUBSTITUTION },
|
||||
{ MAKE_KEY_NAME2(CLS, "CHROME", DDE), "", DDE_COMMAND, NO_SUBSTITUTION | NON_ESSENTIAL },
|
||||
{ MAKE_KEY_NAME3(CLS, "CHROME", DDE, "Application"), "", DDE_NAME, NO_SUBSTITUTION | NON_ESSENTIAL },
|
||||
{ MAKE_KEY_NAME3(CLS, "CHROME", DDE, "Topic"), "", "WWW_OpenURL", NO_SUBSTITUTION | NON_ESSENTIAL },
|
||||
{ MAKE_KEY_NAME3(CLS, "CHROME", DDE, "ifexec"), "", DDE_IFEXEC, NO_SUBSTITUTION },
|
||||
|
||||
// Windows XP Start Menu
|
||||
{ MAKE_KEY_NAME2(SMI, "%APPEXE%", DI),
|
||||
"",
|
||||
"%APPPATH%,0",
|
||||
PATH_SUBSTITUTION | EXE_SUBSTITUTION | NON_ESSENTIAL },
|
||||
APP_PATH_SUBSTITUTION | EXE_NAME_SUBSTITUTION | HKLM_ONLY | NON_ESSENTIAL },
|
||||
{ MAKE_KEY_NAME2(SMI, "%APPEXE%", II),
|
||||
"HideIconsCommand",
|
||||
"\"%UNINSTPATH%\" /HideShortcuts",
|
||||
UNINST_PATH_SUBSTITUTION | EXE_NAME_SUBSTITUTION | HKLM_ONLY | NON_ESSENTIAL },
|
||||
{ MAKE_KEY_NAME2(SMI, "%APPEXE%", II),
|
||||
"ReinstallCommand",
|
||||
"\"%UNINSTPATH%\" /SetAsDefaultAppGlobal",
|
||||
UNINST_PATH_SUBSTITUTION | EXE_NAME_SUBSTITUTION | HKLM_ONLY | NON_ESSENTIAL },
|
||||
{ MAKE_KEY_NAME2(SMI, "%APPEXE%", II),
|
||||
"ShowIconsCommand",
|
||||
"\"%UNINSTPATH%\" /ShowShortcuts",
|
||||
UNINST_PATH_SUBSTITUTION | EXE_NAME_SUBSTITUTION | HKLM_ONLY | NON_ESSENTIAL },
|
||||
{ MAKE_KEY_NAME2(SMI, "%APPEXE%", SOP),
|
||||
"",
|
||||
"%APPPATH%",
|
||||
PATH_SUBSTITUTION | EXE_SUBSTITUTION | NON_ESSENTIAL },
|
||||
APP_PATH_SUBSTITUTION | EXE_NAME_SUBSTITUTION | HKLM_ONLY | NON_ESSENTIAL },
|
||||
{ MAKE_KEY_NAME1(SMI, "%APPEXE%\\shell\\properties\\command"),
|
||||
"",
|
||||
"\"%APPPATH%\" -preferences",
|
||||
PATH_SUBSTITUTION | EXE_SUBSTITUTION | NON_ESSENTIAL },
|
||||
APP_PATH_SUBSTITUTION | EXE_NAME_SUBSTITUTION | HKLM_ONLY | NON_ESSENTIAL },
|
||||
{ MAKE_KEY_NAME1(SMI, "%APPEXE%\\shell\\safemode\\command"),
|
||||
"",
|
||||
"\"%APPPATH%\" -safe-mode",
|
||||
PATH_SUBSTITUTION | EXE_SUBSTITUTION | NON_ESSENTIAL }
|
||||
APP_PATH_SUBSTITUTION | EXE_NAME_SUBSTITUTION | HKLM_ONLY | NON_ESSENTIAL }
|
||||
|
||||
// These values must be set by hand, since they contain localized strings.
|
||||
// firefox.exe\shell\properties (default) REG_SZ Firefox &Options
|
||||
@@ -390,6 +427,12 @@ nsWindowsShellService::SetDefaultBrowserVista()
|
||||
NS_IMETHODIMP
|
||||
nsWindowsShellService::IsDefaultBrowser(PRBool aStartupCheck, PRBool* aIsDefaultBrowser)
|
||||
{
|
||||
// To support side by side installs on Vista we also need to check if the
|
||||
// FirefoxHTML and FirefoxURL registry keys in HKLM / HKCU point to our
|
||||
// install location. If the HKLM keys point to this install location we have
|
||||
// to verify that the keys don't exist in HKCU and remove them if the app is
|
||||
// then set as default. If the HKLM keys don't point to this install location
|
||||
// then we have to add these keys in HKCU to over-ride the HKLM keys.
|
||||
if (IsDefaultBrowserVista(aStartupCheck, aIsDefaultBrowser))
|
||||
return NS_OK;
|
||||
|
||||
@@ -433,7 +476,7 @@ nsWindowsShellService::IsDefaultBrowser(PRBool aStartupCheck, PRBool* aIsDefault
|
||||
nsCAutoString dataLongPath(settings->valueData);
|
||||
nsCAutoString dataShortPath(settings->valueData);
|
||||
nsCAutoString key(settings->keyName);
|
||||
if (settings->flags & PATH_SUBSTITUTION) {
|
||||
if (settings->flags & APP_PATH_SUBSTITUTION) {
|
||||
PRInt32 offset = dataLongPath.Find("%APPPATH%");
|
||||
dataLongPath.Replace(offset, 9, appLongPath);
|
||||
// Remove the quotes around %APPPATH% in VAL_OPEN for short paths
|
||||
@@ -443,7 +486,7 @@ nsWindowsShellService::IsDefaultBrowser(PRBool aStartupCheck, PRBool* aIsDefault
|
||||
else
|
||||
dataShortPath.Replace(offset, 9, appShortPath);
|
||||
}
|
||||
if (settings->flags & EXE_SUBSTITUTION) {
|
||||
if (settings->flags & EXE_NAME_SUBSTITUTION) {
|
||||
PRInt32 offset = key.Find("%APPEXE%");
|
||||
key.Replace(offset, 8, exeName);
|
||||
}
|
||||
@@ -502,26 +545,39 @@ nsWindowsShellService::SetDefaultBrowser(PRBool aClaimAllTypes, PRBool aForAllUs
|
||||
return rv;
|
||||
ToUpperCase(exeName);
|
||||
|
||||
nsCOMPtr<nsIFile> appDir;
|
||||
rv = lf->GetParent(getter_AddRefs(appDir));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
nsCAutoString parentPath;
|
||||
appDir->GetNativePath(parentPath);
|
||||
|
||||
nsCAutoString uninstLongPath(parentPath.get());
|
||||
uninstLongPath.Append(UNINSTALL_EXE);
|
||||
|
||||
for (settings = gSettings; settings < end; ++settings) {
|
||||
nsCAutoString dataLongPath(settings->valueData);
|
||||
nsCAutoString key(settings->keyName);
|
||||
if (settings->flags & PATH_SUBSTITUTION) {
|
||||
if (settings->flags & APP_PATH_SUBSTITUTION) {
|
||||
PRInt32 offset = dataLongPath.Find("%APPPATH%");
|
||||
dataLongPath.Replace(offset, 9, appLongPath);
|
||||
}
|
||||
if (settings->flags & EXE_SUBSTITUTION) {
|
||||
if (settings->flags & UNINST_PATH_SUBSTITUTION) {
|
||||
PRInt32 offset = dataLongPath.Find("%UNINSTPATH%");
|
||||
dataLongPath.Replace(offset, 12, uninstLongPath);
|
||||
}
|
||||
if (settings->flags & EXE_NAME_SUBSTITUTION) {
|
||||
PRInt32 offset = key.Find("%APPEXE%");
|
||||
key.Replace(offset, 8, exeName);
|
||||
}
|
||||
|
||||
PRBool replaceExisting = aClaimAllTypes ? PR_TRUE : !(settings->flags & NON_ESSENTIAL);
|
||||
SetRegKey(key.get(), settings->valueName, dataLongPath.get(),
|
||||
replaceExisting, aForAllUsers);
|
||||
(settings->flags & HKLM_ONLY));
|
||||
}
|
||||
|
||||
// Select the Default Browser for the Windows XP Start Menu
|
||||
SetRegKey(NS_LITERAL_CSTRING(SMI).get(), "", exeName.get(), aClaimAllTypes,
|
||||
aForAllUsers);
|
||||
SetRegKey(NS_LITERAL_CSTRING(SMI).get(), "", exeName.get(), PR_TRUE);
|
||||
|
||||
nsCOMPtr<nsIStringBundleService> bundleService(do_GetService("@mozilla.org/intl/stringbundle;1"));
|
||||
if (!bundleService)
|
||||
@@ -545,8 +601,7 @@ nsWindowsShellService::SetDefaultBrowser(PRBool aClaimAllTypes, PRBool aForAllUs
|
||||
nsCAutoString key1(NS_LITERAL_CSTRING(SMI));
|
||||
key1.Append(exeName);
|
||||
key1.Append("\\");
|
||||
SetRegKey(key1.get(), "", nativeFullName.get(), aClaimAllTypes,
|
||||
aForAllUsers);
|
||||
SetRegKey(key1.get(), "", nativeFullName.get(), PR_TRUE);
|
||||
|
||||
// Set the Options and Safe Mode start menu context menu item labels
|
||||
nsCAutoString optionsKey(SMI);
|
||||
@@ -577,13 +632,11 @@ nsWindowsShellService::SetDefaultBrowser(PRBool aClaimAllTypes, PRBool aForAllUs
|
||||
// For the now, we use 'A' APIs (see bug 240272, 239279)
|
||||
NS_UTF16ToCString(optionsTitle, NS_CSTRING_ENCODING_NATIVE_FILESYSTEM,
|
||||
nativeTitle);
|
||||
SetRegKey(optionsKey.get(), "", nativeTitle.get(), aClaimAllTypes,
|
||||
aForAllUsers);
|
||||
SetRegKey(optionsKey.get(), "", nativeTitle.get(), PR_TRUE);
|
||||
// For the now, we use 'A' APIs (see bug 240272, 239279)
|
||||
NS_UTF16ToCString(safeModeTitle, NS_CSTRING_ENCODING_NATIVE_FILESYSTEM,
|
||||
nativeTitle);
|
||||
SetRegKey(safeModeKey.get(), "", nativeTitle.get(), aClaimAllTypes,
|
||||
aForAllUsers);
|
||||
SetRegKey(safeModeKey.get(), "", nativeTitle.get(), PR_TRUE);
|
||||
|
||||
// Refresh the Shell
|
||||
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, 0, 0);
|
||||
@@ -592,19 +645,14 @@ nsWindowsShellService::SetDefaultBrowser(PRBool aClaimAllTypes, PRBool aForAllUs
|
||||
|
||||
void
|
||||
nsWindowsShellService::SetRegKey(const char* aKeyName, const char* aValueName,
|
||||
const char* aValue, PRBool aReplaceExisting,
|
||||
PRBool aForAllUsers)
|
||||
const char* aValue, PRBool aHKLMOnly)
|
||||
{
|
||||
char buf[MAX_BUF];
|
||||
DWORD len = sizeof buf;
|
||||
|
||||
HKEY theKey;
|
||||
nsresult rv = OpenKeyForWriting(aKeyName, &theKey, aForAllUsers, PR_TRUE);
|
||||
if (NS_FAILED(rv) && rv != NS_ERROR_FILE_NOT_FOUND) return;
|
||||
|
||||
// If we're not allowed to replace an existing key, and one exists (i.e. the
|
||||
// result isn't ERROR_FILE_NOT_FOUND, then just return now.
|
||||
if (!aReplaceExisting && rv != NS_ERROR_FILE_NOT_FOUND)
|
||||
nsresult rv = OpenKeyForWriting(HKEY_LOCAL_MACHINE, aKeyName, &theKey, aHKLMOnly);
|
||||
if (NS_FAILED(rv))
|
||||
return;
|
||||
|
||||
// Get the old value
|
||||
|
||||
@@ -61,8 +61,7 @@ protected:
|
||||
|
||||
PRBool GetMailAccountKey(HKEY* aResult);
|
||||
void SetRegKey(const char* aKeyName, const char* aValueName,
|
||||
const char* aValue, PRBool aReplaceExisting,
|
||||
PRBool aForAllUsers);
|
||||
const char* aValue, PRBool aHKLMOnly);
|
||||
|
||||
private:
|
||||
PRBool mCheckedThisSession;
|
||||
|
||||
@@ -68,5 +68,7 @@ extensions/inspector@mozilla.org/components/inspector.xpt
|
||||
extensions/inspector@mozilla.org/components/@DLL_PREFIX@inspector@DLL_SUFFIX@
|
||||
uninstall/UninstallFirefox.exe
|
||||
uninstall/UninstallDeerPark.exe
|
||||
uninstall/uninst.exe
|
||||
uninstall/uninstall.exe
|
||||
components/myspell/en-US.dic
|
||||
components/myspell/en-US.aff
|
||||
|
||||
@@ -56,6 +56,7 @@ INSTALLER_FILES = \
|
||||
app.tag \
|
||||
nsis/installer.nsi \
|
||||
nsis/uninstaller.nsi \
|
||||
nsis/shared.nsh \
|
||||
$(NULL)
|
||||
|
||||
BRANDING_FILES = \
|
||||
|
||||
@@ -9,3 +9,4 @@
|
||||
!define FileMainEXE "@MOZ_APP_NAME@.exe"
|
||||
!define WindowClass "FirefoxMessageWindow"
|
||||
!define DDEApplication "Firefox"
|
||||
!define AppRegName "Firefox"
|
||||
|
||||
@@ -83,7 +83,6 @@ Var fhUninstallLog
|
||||
!insertmacro GetOptions
|
||||
!insertmacro GetRoot
|
||||
!insertmacro DriveSpace
|
||||
!insertmacro GetParent
|
||||
|
||||
; NSIS provided macros that we have overridden
|
||||
!include overrides.nsh
|
||||
@@ -97,6 +96,8 @@ Var fhUninstallLog
|
||||
!include locales.nsi
|
||||
!include version.nsh
|
||||
|
||||
VIAddVersionKey "FileDescription" "${BrandShortName} Installer"
|
||||
|
||||
!insertmacro RegCleanMain
|
||||
!insertmacro RegCleanUninstall
|
||||
!insertmacro CloseApp
|
||||
@@ -105,9 +106,10 @@ Var fhUninstallLog
|
||||
!insertmacro CreateRegKey
|
||||
!insertmacro CanWriteToInstallDir
|
||||
!insertmacro CheckDiskSpace
|
||||
!insertmacro AddHandlerValues
|
||||
!insertmacro DisplayCopyErrMsg
|
||||
!insertmacro GetExistingInstallPath
|
||||
!insertmacro IsVista
|
||||
|
||||
!include shared.nsh
|
||||
|
||||
Name "${BrandFullName}"
|
||||
OutFile "setup.exe"
|
||||
@@ -432,240 +434,35 @@ Section "-Application" Section1
|
||||
; MUST add children first so they will be removed first on uninstall so they
|
||||
; will be empty when the key is deleted. This allows the uninstaller to
|
||||
; specify that only empty keys will be deleted.
|
||||
${SetAppKeys}
|
||||
|
||||
StrCpy $0 "Software\Mozilla\${BrandFullNameInternal}\${AppVersion} (${AB_CD})\Main"
|
||||
${WriteRegStr2} $TmpVal "$0" "Install Directory" "$INSTDIR" 0
|
||||
${WriteRegStr2} $TmpVal "$0" "PathToExe" "$INSTDIR\${FileMainEXE}" 0
|
||||
${WriteRegStr2} $TmpVal "$0" "Program Folder Path" "$SMPROGRAMS\$StartMenuDir" 0
|
||||
${WriteRegDWORD2} $TmpVal "$0" "Create Quick Launch Shortcut" $AddQuickLaunchSC 0
|
||||
${WriteRegDWORD2} $TmpVal "$0" "Create Desktop Shortcut" $AddDesktopSC 0
|
||||
; XXXrstrong - this should be set in shared.nsh along with "Create Quick
|
||||
; Launch Shortcut" and Create Desktop Shortcut.
|
||||
StrCpy $0 "Software\Mozilla\${BrandFullNameInternal}\${AppVersion} (${AB_CD})\Uninstall"
|
||||
${WriteRegDWORD2} $TmpVal "$0" "Create Start Menu Shortcut" $AddStartMenuSC 0
|
||||
|
||||
StrCpy $0 "Software\Mozilla\${BrandFullNameInternal}\${AppVersion} (${AB_CD})\Uninstall"
|
||||
${WriteRegStr2} $TmpVal "$0" "Uninstall Log Folder" "$INSTDIR\uninstall" 0
|
||||
${WriteRegStr2} $TmpVal "$0" "Description" "${BrandFullNameInternal} (${AppVersion})" 0
|
||||
${FixFileKeys}
|
||||
|
||||
StrCpy $0 "Software\Mozilla\${BrandFullNameInternal}\${AppVersion} (${AB_CD})"
|
||||
${WriteRegStr2} $TmpVal "$0" "" "${AppVersion} (${AB_CD})" 0
|
||||
${FixProtocolKeys}
|
||||
|
||||
StrCpy $0 "Software\Mozilla\${BrandFullNameInternal} ${AppVersion}\bin"
|
||||
${WriteRegStr2} $TmpVal "$0" "PathToExe" "$INSTDIR\${FileMainEXE}" 0
|
||||
; The following keys should only be set if we can write to HKLM
|
||||
${If} $TmpVal == "HKLM"
|
||||
; Uninstall keys can only exist under HKLM on some versions of windows.
|
||||
${SetUninstallKeys}
|
||||
|
||||
StrCpy $0 "Software\Mozilla\${BrandFullNameInternal} ${AppVersion}\extensions"
|
||||
${WriteRegStr2} $TmpVal "$0" "Components" "$INSTDIR\components" 0
|
||||
${WriteRegStr2} $TmpVal "$0" "Plugins" "$INSTDIR\plugins" 0
|
||||
; Set the Start Menu Internet and Vista Registered App HKLM registry keys.
|
||||
${SetStartMenuInternet}
|
||||
|
||||
StrCpy $0 "Software\Mozilla\${BrandFullNameInternal} ${AppVersion}"
|
||||
${WriteRegStr2} $TmpVal "$0" "GeckoVer" "${GREVersion}" 0
|
||||
|
||||
StrCpy $0 "Software\Mozilla\${BrandFullNameInternal}"
|
||||
${WriteRegStr2} $TmpVal "$0" "" "${GREVersion}" 0
|
||||
${WriteRegStr2} $TmpVal "$0" "CurrentVersion" "${AppVersion} (${AB_CD})" 0
|
||||
|
||||
; XXXrstrong - there are several values that will be overwritten by and
|
||||
; overwrite other installs of the same application.
|
||||
${StrFilter} "${FileMainEXE}" "+" "" "" $R9
|
||||
StrCpy $0 "Software\Clients\StartMenuInternet\$R9"
|
||||
${WriteRegStr2} $TmpVal "$0" "" "${BrandShortName}" 0
|
||||
|
||||
StrCpy $0 "Software\Clients\StartMenuInternet\$R9\DefaultIcon"
|
||||
StrCpy $1 "$\"$INSTDIR\${FileMainEXE}$\",0"
|
||||
${WriteRegStr2} $TmpVal "$0" "" "$1" 0
|
||||
|
||||
; The Reinstall Command is defined at
|
||||
; http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/programmersguide/shell_adv/registeringapps.asp
|
||||
StrCpy $0 "Software\Clients\StartMenuInternet\$R9\InstallInfo"
|
||||
StrCpy $1 "$\"$INSTDIR\uninstall\uninst.exe$\" /HideShortcuts"
|
||||
${WriteRegStr2} $TmpVal "$0" "HideIconsCommand" "$1" 0
|
||||
${WriteRegDWORD2} $TmpVal "$0" "IconsVisible" 1 0
|
||||
|
||||
StrCpy $0 "Software\Clients\StartMenuInternet\$R9\InstallInfo"
|
||||
StrCpy $1 "$\"$INSTDIR\${FileMainEXE}$\" -silent -setDefaultBrowser"
|
||||
${WriteRegStr2} $TmpVal "$0" "ReinstallCommand" "$1" 0
|
||||
StrCpy $1 "$\"$INSTDIR\uninstall\uninst.exe$\" /ShowShortcuts"
|
||||
${WriteRegStr2} $TmpVal "$0" "ShowIconsCommand" "$1" 0
|
||||
|
||||
StrCpy $0 "Software\Clients\StartMenuInternet\$R9\shell\open\command"
|
||||
${WriteRegStr2} $TmpVal "$0" "" "$INSTDIR\${FileMainEXE}" 0
|
||||
|
||||
StrCpy $0 "Software\Clients\StartMenuInternet\$R9\shell\properties"
|
||||
${WriteRegStr2} $TmpVal "$0" "" "$(OPTIONS)" 0
|
||||
StrCpy $0 "Software\Clients\StartMenuInternet\$R9\shell\properties\command"
|
||||
${WriteRegStr2} $TmpVal "$0" "" "$INSTDIR\${FileMainEXE} -preferences" 0
|
||||
|
||||
|
||||
|
||||
${IsVista} $R9
|
||||
${If} $R9 == "true"
|
||||
; For Vista these keys and name / value pairs may need to be created during
|
||||
; install.
|
||||
ReadRegStr $0 HKLM "Software\Classes\.shtml" "Content Type"
|
||||
${If} $0 == ""
|
||||
StrCpy $0 "Software\Classes\.shtml"
|
||||
${WriteRegStr2} $TmpVal "$0" "" "FirefoxHTML" 0
|
||||
${WriteRegStr2} $TmpVal "$0" "Content Type" "text/html" 0
|
||||
${WriteRegStr2} $TmpVal "$0" "PerceivedType" "text" 0
|
||||
; If we are writing to HKLM and create the quick launch and the desktop
|
||||
; shortcuts set IconsVisible to 1 otherwise to 0.
|
||||
${If} $AddQuickLaunchSC == 1
|
||||
${OrIf} $AddDesktopSC == 1
|
||||
${StrFilter} "${FileMainEXE}" "+" "" "" $R9
|
||||
StrCpy $0 "Software\Clients\StartMenuInternet\$R9\InstallInfo"
|
||||
WriteRegDWORD HKLM "$0" "IconsVisible" 1
|
||||
${Else}
|
||||
WriteRegDWORD HKLM "$0" "IconsVisible" 0
|
||||
${EndIf}
|
||||
|
||||
ReadRegStr $0 HKLM "Software\Classes\.xht" "Content Type"
|
||||
${If} $0 == ""
|
||||
StrCpy $0 "Software\Classes\.xht"
|
||||
${WriteRegStr2} $TmpVal "$0" "" "FirefoxHTML" 0
|
||||
${WriteRegStr2} $TmpVal "$0" "Content Type" "application/xhtml+xml" 0
|
||||
${EndIf}
|
||||
|
||||
ReadRegStr $0 HKLM "Software\Classes\.xhtml" "Content Type"
|
||||
${If} $0 == ""
|
||||
StrCpy $0 "Software\Classes\.xhtml"
|
||||
${WriteRegStr2} $TmpVal "$0" "" "FirefoxHTML" 0
|
||||
${WriteRegStr2} $TmpVal "$0" "Content Type" "application/xhtml+xml" 0
|
||||
${EndIf}
|
||||
|
||||
ReadRegStr $0 HKLM "Software\Classes\gopher\shell\open\command" ""
|
||||
${If} $0 == ""
|
||||
StrCpy $0 "Software\Classes\gopher"
|
||||
${WriteRegStr2} $TmpVal "$0" "" "URL:Gopher Protocol" 0
|
||||
${WriteRegStr2} $TmpVal "$0" "URL Protocol" "" 0
|
||||
${WriteRegDWORD2} $TmpVal "$0" "EditFlags" 2 0
|
||||
|
||||
StrCpy $0 "Software\Classes\gopher\DefaultIcon"
|
||||
StrCpy $1 "$\"$INSTDIR\${FileMainEXE}$\",0"
|
||||
${WriteRegStr2} $TmpVal "$0" "" "$1" 0
|
||||
|
||||
StrCpy $0 "Software\Classes\gopher\shell\open\command"
|
||||
StrCpy $1 "$\"$INSTDIR\${FileMainEXE}$\" -url $\"%1$\""
|
||||
${WriteRegStr2} $TmpVal "$0" "" "$1" 0
|
||||
|
||||
StrCpy $0 "Software\Classes\gopher\shell\open\ddeexec"
|
||||
StrCpy $1 "$\"%1$\",,0,0,,,,"
|
||||
${WriteRegStr2} $TmpVal "$0" "" "$1" 0
|
||||
${WriteRegStr2} $TmpVal "$0" "NoActivateHandler" "" 0
|
||||
|
||||
StrCpy $0 "Software\Classes\gopher\shell\open\ddeexec\Application"
|
||||
${WriteRegStr2} $TmpVal "$0" "" "${DDEApplication}" 0
|
||||
|
||||
StrCpy $0 "Software\Classes\gopher\shell\open\ddeexec\ifexec"
|
||||
StrCpy $1 ",,0,0,,,,"
|
||||
${WriteRegStr2} $TmpVal "$0" "" "$1" 0
|
||||
|
||||
StrCpy $0 "Software\Classes\gopher\shell\open\ddeexec\Topic"
|
||||
${WriteRegStr2} $TmpVal "$0" "" "WWW_OpenURL" 0
|
||||
${EndIf}
|
||||
|
||||
; Only create the key and its children if it doesn't exist
|
||||
ReadRegStr $0 HKLM "Software\Classes\chrome\shell\open\command" ""
|
||||
${If} $0 == ""
|
||||
StrCpy $0 "Software\Classes\chrome"
|
||||
${WriteRegStr2} $TmpVal "$0" "" "URL:Chrome Protocol" 0
|
||||
${WriteRegStr2} $TmpVal "$0" "URL Protocol" "" 0
|
||||
${WriteRegDWORD2} $TmpVal "$0" "EditFlags" 2 0
|
||||
|
||||
StrCpy $0 "Software\Classes\chrome\DefaultIcon"
|
||||
StrCpy $1 "$\"$INSTDIR\${FileMainEXE}$\",0"
|
||||
${WriteRegStr2} $TmpVal "$0" "" "$1" 0
|
||||
|
||||
StrCpy $0 "Software\Classes\chrome\shell\open\command"
|
||||
StrCpy $1 "$\"$INSTDIR\${FileMainEXE}$\" -url $\"%1$\""
|
||||
${WriteRegStr2} $TmpVal "$0" "" "$1" 0
|
||||
|
||||
StrCpy $0 "Software\Classes\chrome\shell\open\ddeexec"
|
||||
StrCpy $1 "$\"%1$\",,0,0,,,,"
|
||||
${WriteRegStr2} $TmpVal "$0" "" "$1" 0
|
||||
${WriteRegStr2} $TmpVal "$0" "NoActivateHandler" "" 0
|
||||
|
||||
StrCpy $0 "Software\Classes\chrome\shell\open\ddeexec\Application"
|
||||
${WriteRegStr2} $TmpVal "$0" "" "${DDEApplication}" 0
|
||||
|
||||
StrCpy $0 "Software\Classes\chrome\shell\open\ddeexec\ifexec"
|
||||
StrCpy $1 ",,0,0,,,,"
|
||||
${WriteRegStr2} $TmpVal "$0" "" "$1" 0
|
||||
|
||||
StrCpy $0 "Software\Classes\chrome\shell\open\ddeexec\Topic"
|
||||
${WriteRegStr2} $TmpVal "$0" "" "WWW_OpenURL" 0
|
||||
${EndIf}
|
||||
|
||||
; Always set the file and protocol handlers since they may specify a
|
||||
; different path and the path is used by Vista when setting associations.
|
||||
StrCpy $0 "Software\Classes\FirefoxURL"
|
||||
${WriteRegStr2} $TmpVal "$0" "" "Firefox URL" 0
|
||||
${WriteRegStr2} $TmpVal "$0" "FriendlyTypeName" "Firefox URL" 0
|
||||
${WriteRegStr2} $TmpVal "$0" "URL Protocol" "" 0
|
||||
${WriteRegDWORD2} $TmpVal "$0" "EditFlags" 2 0
|
||||
|
||||
StrCpy $0 "Software\Classes\FirefoxURL\DefaultIcon"
|
||||
StrCpy $1 "$\"$INSTDIR\${FileMainEXE}$\",0"
|
||||
${WriteRegStr2} $TmpVal "$0" "" "$1" 0
|
||||
|
||||
StrCpy $0 "Software\Classes\FirefoxURL\shell\open\command"
|
||||
StrCpy $1 "$\"$INSTDIR\${FileMainEXE}$\" -url $\"%1$\""
|
||||
${WriteRegStr2} $TmpVal "$0" "" "$1" 0
|
||||
|
||||
StrCpy $0 "Software\Classes\FirefoxURL\shell\open\ddeexec"
|
||||
StrCpy $1 "$\"%1$\",,0,0,,,,"
|
||||
${WriteRegStr2} $TmpVal "$0" "" "$1" 0
|
||||
${WriteRegStr2} $TmpVal "$0" "NoActivateHandler" "" 0
|
||||
|
||||
StrCpy $0 "Software\Classes\FirefoxURL\shell\open\ddeexec\Application"
|
||||
${WriteRegStr2} $TmpVal "$0" "" "${DDEApplication}" 0
|
||||
|
||||
StrCpy $0 "Software\Classes\FirefoxURL\shell\open\ddeexec\ifexec"
|
||||
StrCpy $1 ",,0,0,,,,"
|
||||
${WriteRegStr2} $TmpVal "$0" "" "$1" 0
|
||||
|
||||
StrCpy $0 "Software\Classes\FirefoxURL\shell\open\ddeexec\Topic"
|
||||
${WriteRegStr2} $TmpVal "$0" "" "WWW_OpenURL" 0
|
||||
|
||||
StrCpy $0 "Software\Classes\FirefoxHTML\DefaultIcon"
|
||||
StrCpy $1 "$\"$INSTDIR\${FileMainEXE}$\",1"
|
||||
${WriteRegStr2} $TmpVal "$0" "" "$1" 0
|
||||
|
||||
StrCpy $0 "Software\Classes\FirefoxHTML\shell\open\command"
|
||||
StrCpy $1 "$\"$INSTDIR\${FileMainEXE}$\" -url $\"%1$\""
|
||||
${WriteRegStr2} $TmpVal "$0" "" "$1" 0
|
||||
|
||||
StrCpy $0 "Software\Classes\FirefoxHTML\shell\open\ddeexec"
|
||||
StrCpy $1 "$\"%1$\",,0,0,,,,"
|
||||
${WriteRegStr2} $TmpVal "$0" "" "$1" 0
|
||||
${WriteRegStr2} $TmpVal "$0" "NoActivateHandler" "" 0
|
||||
|
||||
StrCpy $0 "Software\Classes\FirefoxHTML\shell\open\ddeexec\Application"
|
||||
${WriteRegStr2} $TmpVal "$0" "" "${DDEApplication}" 0
|
||||
|
||||
StrCpy $0 "Software\Classes\FirefoxHTML\shell\open\ddeexec\ifexec"
|
||||
StrCpy $1 ",,0,0,,,,"
|
||||
${WriteRegStr2} $TmpVal "$0" "" "$1" 0
|
||||
|
||||
StrCpy $0 "Software\Classes\FirefoxHTML\shell\open\ddeexec\Topic"
|
||||
${WriteRegStr2} $TmpVal "$0" "" "WWW_OpenURL" 0
|
||||
|
||||
; Vista Registered Application
|
||||
${StrFilter} "${FileMainEXE}" "+" "" "" $R9
|
||||
StrCpy $0 "Software\RegisteredApplications"
|
||||
StrCpy $1 "Software\Clients\StartMenuInternet\$R9\Capabilities"
|
||||
${WriteRegStr2} $TmpVal "$0" "${DDEApplication}" "$1" 0
|
||||
|
||||
; Vista Capabilities registry keys
|
||||
StrCpy $0 "Software\Clients\StartMenuInternet\$R9\Capabilities"
|
||||
StrCpy $1 "$\"$INSTDIR\${FileMainEXE}$\",0"
|
||||
${WriteRegStr2} $TmpVal "$0" "ApplicationDescription" "$(REG_APP_DESC)" 0
|
||||
${WriteRegStr2} $TmpVal "$0" "ApplicationIcon" "$1" 0
|
||||
|
||||
StrCpy $0 "Software\Clients\StartMenuInternet\$R9\Capabilities\FileAssociations"
|
||||
${WriteRegStr2} $TmpVal "$0" ".htm" "FirefoxHTML" 0
|
||||
${WriteRegStr2} $TmpVal "$0" ".html" "FirefoxHTML" 0
|
||||
${WriteRegStr2} $TmpVal "$0" ".shtml" "FirefoxHTML" 0
|
||||
${WriteRegStr2} $TmpVal "$0" ".xht" "FirefoxHTML" 0
|
||||
${WriteRegStr2} $TmpVal "$0" ".xhtml" "FirefoxHTML" 0
|
||||
|
||||
StrCpy $0 "Software\Clients\StartMenuInternet\$R9\Capabilities\StartMenu"
|
||||
${WriteRegStr2} $TmpVal "$0" "StartMenuInternet" "$R9" 0
|
||||
|
||||
StrCpy $0 "Software\Clients\StartMenuInternet\$R9\Capabilities\URLAssociations"
|
||||
${WriteRegStr2} $TmpVal "$0" "chrome" "FirefoxURL" 0
|
||||
${WriteRegStr2} $TmpVal "$0" "ftp" "FirefoxURL" 0
|
||||
${WriteRegStr2} $TmpVal "$0" "gopher" "FirefoxURL" 0
|
||||
${WriteRegStr2} $TmpVal "$0" "http" "FirefoxURL" 0
|
||||
${WriteRegStr2} $TmpVal "$0" "https" "FirefoxURL" 0
|
||||
${EndIf}
|
||||
|
||||
; These need special handling on uninstall since they may be overwritten by
|
||||
@@ -674,27 +471,9 @@ Section "-Application" Section1
|
||||
${WriteRegStr2} $TmpVal "$0" "" "$INSTDIR\${FileMainEXE}" 0
|
||||
${WriteRegStr2} $TmpVal "$0" "Path" "$INSTDIR" 0
|
||||
|
||||
StrCpy $0 "Software\Classes\MIME\Database\Content Type\application/x-xpinstall;app=firefox"
|
||||
${WriteRegStr2} $TmpVal "$0" "Extension" ".xpi" 0
|
||||
|
||||
StrCpy $0 "Software\Microsoft\MediaPlayer\ShimInclusionList\$R9"
|
||||
${CreateRegKey} "$TmpVal" "$0" 0
|
||||
|
||||
; Write the uninstall registry keys
|
||||
StrCpy $0 "Software\Microsoft\Windows\CurrentVersion\Uninstall\${BrandFullNameInternal} (${AppVersion})"
|
||||
StrCpy $1 "$INSTDIR\uninstall\uninst.exe"
|
||||
|
||||
${WriteRegStr2} $TmpVal "$0" "Comments" "${BrandFullNameInternal}" 0
|
||||
${WriteRegStr2} $TmpVal "$0" "DisplayIcon" "$INSTDIR\${FileMainEXE},0" 0
|
||||
${WriteRegStr2} $TmpVal "$0" "DisplayName" "${BrandFullNameInternal} (${AppVersion})" 0
|
||||
${WriteRegStr2} $TmpVal "$0" "DisplayVersion" "${AppVersion} (${AB_CD})" 0
|
||||
${WriteRegStr2} $TmpVal "$0" "InstallLocation" "$INSTDIR" 0
|
||||
${WriteRegStr2} $TmpVal "$0" "Publisher" "Mozilla" 0
|
||||
${WriteRegStr2} $TmpVal "$0" "UninstallString" "$1" 0
|
||||
${WriteRegStr2} $TmpVal "$0" "URLInfoAbout" "${URLInfoAbout}" 0
|
||||
${WriteRegStr2} $TmpVal "$0" "URLUpdateInfo" "${URLUpdateInfo}" 0
|
||||
${WriteRegDWORD2} $TmpVal "$0" "NoModify" 1 0
|
||||
${WriteRegDWORD2} $TmpVal "$0" "NoRepair" 1 0
|
||||
!insertmacro MUI_STARTMENU_WRITE_BEGIN Application
|
||||
|
||||
; Create Start Menu shortcuts
|
||||
@@ -905,7 +684,7 @@ Function CopyFile
|
||||
; If the file is installed into the installation directory remove the
|
||||
; installation directory's path from the file path when writing to the
|
||||
; uninstall.log so it will be a relative path. This allows the same
|
||||
; uninst.exe to be used with zip builds if we supply an uninstall.log.
|
||||
; helper.exe to be used with zip builds if we supply an uninstall.log.
|
||||
${WordReplace} "$R1$R3\$R7" "$INSTDIR" "" "+" $R3
|
||||
${LogUninstall} "File: $R3"
|
||||
${EndIf}
|
||||
@@ -1067,22 +846,6 @@ Function leaveComponents
|
||||
FunctionEnd
|
||||
|
||||
Function preDirectory
|
||||
${IsVista} $R9
|
||||
${If} $R9 == "true"
|
||||
SetShellVarContext all ; Set SHCTX to HKLM
|
||||
${GetExistingInstallPath} "Software\Mozilla" $R9
|
||||
${If} $R9 != "false"
|
||||
StrCpy $INSTDIR "$R9"
|
||||
${CheckDiskSpace} $R9
|
||||
${If} $R9 == "true"
|
||||
${CanWriteToInstallDir} $R9
|
||||
${If} $R9 == "true"
|
||||
Abort
|
||||
${EndIf}
|
||||
${EndIf}
|
||||
${EndIf}
|
||||
${EndIf}
|
||||
|
||||
${If} $InstallType != 4
|
||||
${CheckDiskSpace} $R9
|
||||
${If} $R9 != "false"
|
||||
|
||||
373
mozilla/browser/installer/windows/nsis/shared.nsh
Executable file
373
mozilla/browser/installer/windows/nsis/shared.nsh
Executable file
@@ -0,0 +1,373 @@
|
||||
# ***** 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 the Mozilla Installer code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Mozilla Foundation
|
||||
# Portions created by the Initial Developer are Copyright (C) 2006
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Robert Strong <robert.bugzilla@gmail.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 *****
|
||||
|
||||
!macro PostUpdate
|
||||
SetShellVarContext all
|
||||
${SetStartMenuInternet}
|
||||
|
||||
; Remove registry entries for non-existent apps and for apps that point to our
|
||||
; install location in the Software\Mozilla key.
|
||||
SetShellVarContext current ; Set SHCTX to HKCU
|
||||
${RegCleanMain} "Software\Mozilla"
|
||||
SetShellVarContext all ; Set SHCTX to HKLM
|
||||
${RegCleanMain} "Software\Mozilla"
|
||||
|
||||
; Remove uninstall entries that point to our install location
|
||||
${RegCleanUninstall}
|
||||
|
||||
; Add Software\Mozilla\ registry entries
|
||||
${SetAppKeys}
|
||||
|
||||
${SetUninstallKeys}
|
||||
|
||||
${FixFileKeys}
|
||||
|
||||
${FixProtocolKeys}
|
||||
|
||||
!macroend
|
||||
!define PostUpdate "!insertmacro PostUpdate"
|
||||
|
||||
!macro SetAsDefaultAppUser
|
||||
SetShellVarContext current
|
||||
${SetHandlers}
|
||||
!macroend
|
||||
!define SetAsDefaultAppUser "!insertmacro SetAsDefaultAppUser"
|
||||
|
||||
!macro SetAsDefaultAppGlobal
|
||||
SetShellVarContext all
|
||||
${SetHandlers}
|
||||
${SetStartMenuInternet}
|
||||
WriteRegStr HKLM "Software\Clients\StartMenuInternet" "" "$R9"
|
||||
${ShowShortcuts}
|
||||
!macroend
|
||||
!define SetAsDefaultAppGlobal "!insertmacro SetAsDefaultAppGlobal"
|
||||
|
||||
!macro HideShortcuts
|
||||
${StrFilter} "${FileMainEXE}" "+" "" "" $0
|
||||
StrCpy $R1 "Software\Clients\StartMenuInternet\$0\InstallInfo"
|
||||
WriteRegDWORD HKLM $R1 "IconsVisible" 0
|
||||
SetShellVarContext all ; Set $DESKTOP to All Users
|
||||
${Unless} ${FileExists} "$DESKTOP\${BrandFullName}.lnk"
|
||||
SetShellVarContext current ; Set $DESKTOP to the current user's desktop
|
||||
${EndUnless}
|
||||
|
||||
${If} ${FileExists} "$DESKTOP\${BrandFullName}.lnk"
|
||||
ShellLink::GetShortCutArgs "$DESKTOP\${BrandFullName}.lnk"
|
||||
Pop $0
|
||||
${If} $0 == ""
|
||||
ShellLink::GetShortCutTarget "$DESKTOP\${BrandFullName}.lnk"
|
||||
Pop $0
|
||||
; Needs to handle short paths
|
||||
${If} $0 == "$INSTDIR\${FileMainEXE}"
|
||||
Delete "$DESKTOP\${BrandFullName}.lnk"
|
||||
${EndIf}
|
||||
${EndIf}
|
||||
${EndIf}
|
||||
|
||||
${If} ${FileExists} "$QUICKLAUNCH\${BrandFullName}.lnk"
|
||||
ShellLink::GetShortCutArgs "$QUICKLAUNCH\${BrandFullName}.lnk"
|
||||
Pop $0
|
||||
${If} $0 == ""
|
||||
ShellLink::GetShortCutTarget "$QUICKLAUNCH\${BrandFullName}.lnk"
|
||||
Pop $0
|
||||
; Needs to handle short paths
|
||||
${If} $0 == "$INSTDIR\${FileMainEXE}"
|
||||
Delete "$QUICKLAUNCH\${BrandFullName}.lnk"
|
||||
${EndIf}
|
||||
${EndIf}
|
||||
${EndIf}
|
||||
!macroend
|
||||
!define HideShortcuts "!insertmacro HideShortcuts"
|
||||
|
||||
!macro ShowShortcuts
|
||||
${StrFilter} "${FileMainEXE}" "+" "" "" $0
|
||||
StrCpy $R1 "Software\Clients\StartMenuInternet\$0\InstallInfo"
|
||||
WriteRegDWORD HKLM $R1 "IconsVisible" 1
|
||||
SetShellVarContext all ; Set $DESKTOP to All Users
|
||||
${Unless} ${FileExists} "$DESKTOP\${BrandFullName}.lnk"
|
||||
CreateShortCut "$DESKTOP\${BrandFullName}.lnk" "$INSTDIR\${FileMainEXE}" "" "$INSTDIR\${FileMainEXE}" 0
|
||||
ShellLink::SetShortCutWorkingDirectory "$DESKTOP\${BrandFullName}.lnk" "$INSTDIR"
|
||||
${Unless} ${FileExists} "$DESKTOP\${BrandFullName}.lnk"
|
||||
SetShellVarContext current ; Set $DESKTOP to the current user's desktop
|
||||
${Unless} ${FileExists} "$DESKTOP\${BrandFullName}.lnk"
|
||||
CreateShortCut "$DESKTOP\${BrandFullName}.lnk" "$INSTDIR\${FileMainEXE}" "" "$INSTDIR\${FileMainEXE}" 0
|
||||
ShellLink::SetShortCutWorkingDirectory "$DESKTOP\${BrandFullName}.lnk" "$INSTDIR"
|
||||
${EndUnless}
|
||||
${EndUnless}
|
||||
${EndUnless}
|
||||
${Unless} ${FileExists} "$QUICKLAUNCH\${BrandFullName}.lnk"
|
||||
CreateShortCut "$QUICKLAUNCH\${BrandFullName}.lnk" "$INSTDIR\${FileMainEXE}" "" "$INSTDIR\${FileMainEXE}" 0
|
||||
ShellLink::SetShortCutWorkingDirectory "$QUICKLAUNCH\${BrandFullName}.lnk" "$INSTDIR"
|
||||
${EndUnless}
|
||||
!macroend
|
||||
!define ShowShortcuts "!insertmacro ShowShortcuts"
|
||||
|
||||
!macro SetHandlers
|
||||
GetFullPathName $8 "$INSTDIR\${FileMainEXE}"
|
||||
|
||||
StrCpy $0 "SOFTWARE\Classes"
|
||||
StrCpy $2 "$\"$8$\" -url $\"%1$\" -requestPending"
|
||||
|
||||
; Associate the file handlers with FirefoxHTML
|
||||
WriteRegStr SHCTX "$0\.htm" "" "FirefoxHTML"
|
||||
WriteRegStr SHCTX "$0\.html" "" "FirefoxHTML"
|
||||
WriteRegStr SHCTX "$0\.shtml" "" "FirefoxHTML"
|
||||
WriteRegStr SHCTX "$0\.xht" "" "FirefoxHTML"
|
||||
WriteRegStr SHCTX "$0\.xhtml" "" "FirefoxHTML"
|
||||
|
||||
; An empty string is used for the 5th param because FirefoxHTML is not a
|
||||
; protocol handler
|
||||
${AddHandlerValues} "$0\FirefoxHTML" "$2" "$8,1" "${AppRegName} Document" "" "true"
|
||||
|
||||
${AddHandlerValues} "$0\FirefoxURL" "$2" "$8,0" "${AppRegName} URL" "true" "true"
|
||||
${AddHandlerValues} "$0\gopher" "$2" "$8,0" "URL:Gopher Protocol" "true" "true"
|
||||
|
||||
; An empty string is used for the 4th & 5th params because the following
|
||||
; protocol handlers already have a display name and additional keys required
|
||||
; for a protocol handler.
|
||||
${AddHandlerValues} "$0\ftp" "$2" "$8,0" "" "" "true"
|
||||
${AddHandlerValues} "$0\http" "$2" "$8,0" "" "" "true"
|
||||
${AddHandlerValues} "$0\https" "$2" "$8,0" "" "" "true"
|
||||
!macroend
|
||||
!define SetHandlers "!insertmacro SetHandlers"
|
||||
|
||||
; XXXrstrong - there are several values that will be overwritten by and
|
||||
; overwrite other installs of the same application.
|
||||
!macro SetStartMenuInternet
|
||||
GetFullPathName $8 "$INSTDIR\${FileMainEXE}"
|
||||
GetFullPathName $7 "$INSTDIR\uninstall\helper.exe"
|
||||
|
||||
${StrFilter} "${FileMainEXE}" "+" "" "" $R9
|
||||
|
||||
StrCpy $0 "Software\Clients\StartMenuInternet\$R9"
|
||||
; Remove existing keys so we only have our settings
|
||||
DeleteRegKey HKLM "$0"
|
||||
WriteRegStr HKLM "$0" "" "${BrandFullName}"
|
||||
|
||||
WriteRegStr HKLM "$0\DefaultIcon" "" "$8,0"
|
||||
|
||||
; The Reinstall Command is defined at
|
||||
; http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/programmersguide/shell_adv/registeringapps.asp
|
||||
WriteRegStr HKLM "$0\InstallInfo" "HideIconsCommand" "$\"$7$\" /HideShortcuts"
|
||||
WriteRegStr HKLM "$0\InstallInfo" "ShowIconsCommand" "$\"$7$\" /ShowShortcuts"
|
||||
WriteRegStr HKLM "$0\InstallInfo" "ReinstallCommand" "$\"$7$\" /SetAsDefaultAppGlobal"
|
||||
|
||||
WriteRegStr HKLM "$0\shell\open\command" "" "$8"
|
||||
|
||||
WriteRegStr HKLM "$0\shell\properties" "" "$(CONTEXT_OPTIONS)"
|
||||
WriteRegStr HKLM "$0\shell\properties\command" "" "$\"$8$\" -preferences"
|
||||
|
||||
WriteRegStr HKLM "$0\shell\safemode" "" "$(CONTEXT_SAFE_MODE)"
|
||||
WriteRegStr HKLM "$0\shell\safemode\command" "" "$\"$8$\" -safemode"
|
||||
|
||||
; Vista Capabilities registry keys
|
||||
WriteRegStr HKLM "$0\Capabilities" "ApplicationDescription" "$(REG_APP_DESC)"
|
||||
WriteRegStr HKLM "$0\Capabilities" "ApplicationIcon" "$8,0"
|
||||
WriteRegStr HKLM "$0\Capabilities" "ApplicationName" "${BrandShortName}"
|
||||
|
||||
WriteRegStr HKLM "$0\Capabilities\FileAssociations" ".htm" "FirefoxHTML"
|
||||
WriteRegStr HKLM "$0\Capabilities\FileAssociations" ".html" "FirefoxHTML"
|
||||
WriteRegStr HKLM "$0\Capabilities\FileAssociations" ".shtml" "FirefoxHTML"
|
||||
WriteRegStr HKLM "$0\Capabilities\FileAssociations" ".xht" "FirefoxHTML"
|
||||
WriteRegStr HKLM "$0\Capabilities\FileAssociations" ".xhtml" "FirefoxHTML"
|
||||
|
||||
WriteRegStr HKLM "$0\Capabilities\StartMenu" "StartMenuInternet" "$R9"
|
||||
|
||||
WriteRegStr HKLM "$0\Capabilities\URLAssociations" "ftp" "FirefoxURL"
|
||||
WriteRegStr HKLM "$0\Capabilities\URLAssociations" "gopher" "FirefoxURL"
|
||||
WriteRegStr HKLM "$0\Capabilities\URLAssociations" "http" "FirefoxURL"
|
||||
WriteRegStr HKLM "$0\Capabilities\URLAssociations" "https" "FirefoxURL"
|
||||
|
||||
; Vista Registered Application
|
||||
WriteRegStr HKLM "Software\RegisteredApplications" "${AppRegName}" "$0\Capabilities"
|
||||
!macroend
|
||||
!define SetStartMenuInternet "!insertmacro SetStartMenuInternet"
|
||||
|
||||
!macro SetAppKeys
|
||||
StrCpy $0 "Software\Mozilla\${BrandFullNameInternal}\${AppVersion} (${AB_CD})\Main"
|
||||
${WriteRegStr2} $TmpVal "$0" "Install Directory" "$INSTDIR" 0
|
||||
${WriteRegStr2} $TmpVal "$0" "PathToExe" "$INSTDIR\${FileMainEXE}" 0
|
||||
${WriteRegStr2} $TmpVal "$0" "Program Folder Path" "$SMPROGRAMS\$StartMenuDir" 0
|
||||
|
||||
SetShellVarContext all ; Set $DESKTOP to All Users
|
||||
${Unless} ${FileExists} "$DESKTOP\${BrandFullName}.lnk"
|
||||
SetShellVarContext current ; Set $DESKTOP to the current user's desktop
|
||||
${EndUnless}
|
||||
|
||||
${If} ${FileExists} "$DESKTOP\${BrandFullName}.lnk"
|
||||
ShellLink::GetShortCutArgs "$DESKTOP\${BrandFullName}.lnk"
|
||||
Pop $1
|
||||
${If} $1 == ""
|
||||
ShellLink::GetShortCutTarget "$DESKTOP\${BrandFullName}.lnk"
|
||||
Pop $1
|
||||
; Needs to handle short paths
|
||||
${If} $1 == "$INSTDIR\${FileMainEXE}"
|
||||
${WriteRegDWORD2} $TmpVal "$0" "Create Desktop Shortcut" 1 0
|
||||
${Else}
|
||||
${WriteRegDWORD2} $TmpVal "$0" "Create Desktop Shortcut" 0 0
|
||||
${EndIf}
|
||||
${EndIf}
|
||||
${EndIf}
|
||||
|
||||
; XXXrstrong - need a cleaner way to prevent unsetting SHCTX from HKLM when
|
||||
; trying to find the desktop shortcut.
|
||||
${If} $TmpVal == "HKCU"
|
||||
SetShellVarContext current
|
||||
${Else}
|
||||
SetShellVarContext all
|
||||
${EndIf}
|
||||
|
||||
${If} ${FileExists} "$QUICKLAUNCH\${BrandFullName}.lnk"
|
||||
ShellLink::GetShortCutArgs "$QUICKLAUNCH\${BrandFullName}.lnk"
|
||||
Pop $1
|
||||
${If} $1 == ""
|
||||
ShellLink::GetShortCutTarget "$QUICKLAUNCH\${BrandFullName}.lnk"
|
||||
Pop $1
|
||||
; Needs to handle short paths
|
||||
${If} $1 == "$INSTDIR\${FileMainEXE}"
|
||||
${WriteRegDWORD2} $TmpVal "$0" "Create Quick Launch Shortcut" 1 0
|
||||
${Else}
|
||||
${WriteRegDWORD2} $TmpVal "$0" "Create Quick Launch Shortcut" 0 0
|
||||
${EndIf}
|
||||
${EndIf}
|
||||
${EndIf}
|
||||
; XXXrstrong - "Create Start Menu Shortcut" and "Start Menu Folder" are only
|
||||
; set in the installer and should also be set here for software update.
|
||||
|
||||
StrCpy $0 "Software\Mozilla\${BrandFullNameInternal}\${AppVersion} (${AB_CD})\Uninstall"
|
||||
${WriteRegStr2} $TmpVal "$0" "Uninstall Log Folder" "$INSTDIR\uninstall" 0
|
||||
${WriteRegStr2} $TmpVal "$0" "Description" "${BrandFullNameInternal} (${AppVersion})" 0
|
||||
|
||||
StrCpy $0 "Software\Mozilla\${BrandFullNameInternal}\${AppVersion} (${AB_CD})"
|
||||
${WriteRegStr2} $TmpVal "$0" "" "${AppVersion} (${AB_CD})" 0
|
||||
|
||||
StrCpy $0 "Software\Mozilla\${BrandFullNameInternal} ${AppVersion}\bin"
|
||||
${WriteRegStr2} $TmpVal "$0" "PathToExe" "$INSTDIR\${FileMainEXE}" 0
|
||||
|
||||
StrCpy $0 "Software\Mozilla\${BrandFullNameInternal} ${AppVersion}\extensions"
|
||||
${WriteRegStr2} $TmpVal "$0" "Components" "$INSTDIR\components" 0
|
||||
${WriteRegStr2} $TmpVal "$0" "Plugins" "$INSTDIR\plugins" 0
|
||||
|
||||
StrCpy $0 "Software\Mozilla\${BrandFullNameInternal} ${AppVersion}"
|
||||
${WriteRegStr2} $TmpVal "$0" "GeckoVer" "${GREVersion}" 0
|
||||
|
||||
StrCpy $0 "Software\Mozilla\${BrandFullNameInternal}"
|
||||
${WriteRegStr2} $TmpVal "$0" "" "${GREVersion}" 0
|
||||
${WriteRegStr2} $TmpVal "$0" "CurrentVersion" "${AppVersion} (${AB_CD})" 0
|
||||
!macroend
|
||||
!define SetAppKeys "!insertmacro SetAppKeys"
|
||||
|
||||
!macro SetUninstallKeys
|
||||
; Write the uninstall registry keys
|
||||
StrCpy $0 "Software\Microsoft\Windows\CurrentVersion\Uninstall\${BrandFullNameInternal} (${AppVersion})"
|
||||
GetFullPathName $8 "$INSTDIR\${FileMainEXE}"
|
||||
GetFullPathName $7 "$INSTDIR\uninstall\helper.exe"
|
||||
|
||||
${WriteRegStr2} $TmpVal "$0" "Comments" "${BrandFullNameInternal}" 0
|
||||
${WriteRegStr2} $TmpVal "$0" "DisplayIcon" "$8,0" 0
|
||||
${WriteRegStr2} $TmpVal "$0" "DisplayName" "${BrandFullNameInternal} (${AppVersion})" 0
|
||||
${WriteRegStr2} $TmpVal "$0" "DisplayVersion" "${AppVersion} (${AB_CD})" 0
|
||||
${WriteRegStr2} $TmpVal "$0" "InstallLocation" "$INSTDIR" 0
|
||||
${WriteRegStr2} $TmpVal "$0" "Publisher" "Mozilla" 0
|
||||
${WriteRegStr2} $TmpVal "$0" "UninstallString" "$7" 0
|
||||
${WriteRegStr2} $TmpVal "$0" "URLInfoAbout" "${URLInfoAbout}" 0
|
||||
${WriteRegStr2} $TmpVal "$0" "URLUpdateInfo" "${URLUpdateInfo}" 0
|
||||
${WriteRegDWORD2} $TmpVal "$0" "NoModify" 1 0
|
||||
${WriteRegDWORD2} $TmpVal "$0" "NoRepair" 1 0
|
||||
!macroend
|
||||
!define SetUninstallKeys "!insertmacro SetUninstallKeys"
|
||||
|
||||
; File handler keys and name value pairs that may need to be created during
|
||||
; install or upgrade.
|
||||
!macro FixFileKeys
|
||||
ReadRegStr $0 HKLM "Software\Classes\.shtml" "Content Type"
|
||||
${If} $0 == ""
|
||||
StrCpy $0 "Software\Classes\.shtml"
|
||||
${WriteRegStr2} $TmpVal "$0" "" "shtmlfile" 0
|
||||
${WriteRegStr2} $TmpVal "$0" "Content Type" "text/html" 0
|
||||
${WriteRegStr2} $TmpVal "$0" "PerceivedType" "text" 0
|
||||
${EndIf}
|
||||
|
||||
ReadRegStr $0 HKLM "Software\Classes\.xht" "Content Type"
|
||||
${If} $0 == ""
|
||||
StrCpy $0 "Software\Classes\.xht"
|
||||
${WriteRegStr2} $TmpVal "$0" "" "xhtfile" 0
|
||||
${WriteRegStr2} $TmpVal "$0" "Content Type" "application/xhtml+xml" 0
|
||||
${EndIf}
|
||||
|
||||
ReadRegStr $0 HKLM "Software\Classes\.xhtml" "Content Type"
|
||||
${If} $0 == ""
|
||||
StrCpy $0 "Software\Classes\.xhtml"
|
||||
${WriteRegStr2} $TmpVal "$0" "" "xhtmlfile" 0
|
||||
${WriteRegStr2} $TmpVal "$0" "Content Type" "application/xhtml+xml" 0
|
||||
${EndIf}
|
||||
!macroend
|
||||
!define FixFileKeys "!insertmacro FixFileKeys"
|
||||
|
||||
; Protocol handler keys and name value pairs that may need to be updated during
|
||||
; install or upgrade.
|
||||
!macro FixProtocolKeys
|
||||
; Bug 301073 Comment #9 makes it so Firefox no longer supports launching
|
||||
; chrome urls from the shell so remove it during install or update if the
|
||||
; DefaultIcon is from firefox.exe.
|
||||
ReadRegStr $0 HKLM "Software\Classes\chrome\DefaultIcon" ""
|
||||
${Unless} $0 == ""
|
||||
StrCpy $0 "$0" "" -13
|
||||
StrCpy $0 "$0" 11
|
||||
${If} "$0" == "firefox.exe"
|
||||
DeleteRegKey HKLM "Software\Classes\chrome"
|
||||
${EndIf}
|
||||
${EndUnless}
|
||||
|
||||
; Store the command to open the app with an url in a register for easy access.
|
||||
GetFullPathName $8 "$INSTDIR\${FileMainEXE}"
|
||||
StrCpy $1 "$\"$8$\" -url $\"%1$\" -requestPending"
|
||||
|
||||
; Only set the gopher key if it doesn't already exist with a default value
|
||||
ReadRegStr $0 HKLM "Software\Classes\gopher" ""
|
||||
${If} $0 == ""
|
||||
${AddHandlerValues} "Software\Classes\gopher" "$1" "$8,0" "URL:Gopher Protocol" "true" "true"
|
||||
${EndIf}
|
||||
|
||||
; Always set the file and protocol handlers since they may specify a
|
||||
; different path and the path is used by Vista when setting associations.
|
||||
${AddHandlerValues} "Software\Classes\FirefoxURL" "$1" "$8,0" "${AppRegName} URL" "true" "true"
|
||||
|
||||
; An empty string is used for the 5th param because FirefoxHTML is not a
|
||||
; protocol handler
|
||||
${AddHandlerValues} "Software\Classes\FirefoxHTML" "$1" "$8,1" "${AppRegName} Document" "" "true"
|
||||
!macroend
|
||||
!define FixProtocolKeys "!insertmacro FixProtocolKeys"
|
||||
@@ -48,6 +48,9 @@ CRCCheck on
|
||||
|
||||
!addplugindir ./
|
||||
|
||||
; prevents compiling of the reg write logging.
|
||||
!define NO_LOG
|
||||
|
||||
Var TmpVal
|
||||
|
||||
; Other included files may depend upon these includes!
|
||||
@@ -59,7 +62,11 @@ Var TmpVal
|
||||
!include WordFunc.nsh
|
||||
!include MUI.nsh
|
||||
|
||||
!insertmacro GetOptions
|
||||
!insertmacro GetParameters
|
||||
!insertmacro StrFilter
|
||||
!insertmacro WordReplace
|
||||
|
||||
!insertmacro un.LineFind
|
||||
!insertmacro un.TrimNewLines
|
||||
|
||||
@@ -70,14 +77,24 @@ Var TmpVal
|
||||
!include locales.nsi
|
||||
!include version.nsh
|
||||
|
||||
; This is named BrandShortName helper because we use this for software update
|
||||
; post update cleanup.
|
||||
VIAddVersionKey "FileDescription" "${BrandShortName} Helper"
|
||||
|
||||
!insertmacro AddHandlerValues
|
||||
!insertmacro RegCleanMain
|
||||
!insertmacro RegCleanUninstall
|
||||
!insertmacro WriteRegStr2
|
||||
!insertmacro WriteRegDWORD2
|
||||
!insertmacro un.RegCleanMain
|
||||
!insertmacro un.RegCleanUninstall
|
||||
!insertmacro un.CloseApp
|
||||
!insertmacro un.GetSecondInstallPath
|
||||
!insertmacro un.IsVista
|
||||
|
||||
!include shared.nsh
|
||||
|
||||
Name "${BrandFullName}"
|
||||
OutFile "uninst.exe"
|
||||
OutFile "helper.exe"
|
||||
InstallDirRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${BrandFullNameInternal} (${AppVersion})" "InstallLocation"
|
||||
InstallDir "$PROGRAMFILES\${BrandFullName}"
|
||||
ShowUnInstDetails nevershow
|
||||
@@ -173,18 +190,19 @@ Section "Uninstall"
|
||||
; installing even if there is another install of Firefox that is set as the
|
||||
; default browser. Now the key is always updated on install but it is only
|
||||
; removed if it refers to this install location.
|
||||
${If} $INSTDIR == $R1
|
||||
${If} "$INSTDIR" == "$R1"
|
||||
; XXXrstrong - if there is another installation of the same app ideally we
|
||||
; would just modify these values. The GetSecondInstallPath macro could be
|
||||
; made to provide enough information to do this.
|
||||
DeleteRegKey HKLM "Software\Clients\StartMenuInternet\${FileMainEXE}"
|
||||
DeleteRegValue HKLM "Software\RegisteredApplications" "${AppRegName}"
|
||||
${EndIf}
|
||||
|
||||
StrCpy $0 "Software\Microsoft\Windows\CurrentVersion\App Paths\${FileMainEXE}"
|
||||
${If} $R9 == "false"
|
||||
DeleteRegKey HKLM "$0"
|
||||
DeleteRegKey HKCU "$0"
|
||||
StrCpy $0 "Software\Microsoft\MediaPlayer\ShimInclusionList\$R9"
|
||||
StrCpy $0 "Software\Microsoft\MediaPlayer\ShimInclusionList\${FileMainEXE}"
|
||||
DeleteRegKey HKLM "$0"
|
||||
DeleteRegKey HKCU "$0"
|
||||
StrCpy $0 "MIME\Database\Content Type\application/x-xpinstall;app=firefox"
|
||||
@@ -197,7 +215,7 @@ Section "Uninstall"
|
||||
Push $R0
|
||||
${GetParentDir}
|
||||
Pop $R1
|
||||
${If} $INSTDIR == $R1
|
||||
${If} "$INSTDIR" == "$R1"
|
||||
WriteRegStr HKLM "$0" "" "$R9"
|
||||
Push $R9
|
||||
${GetParentDir}
|
||||
@@ -206,11 +224,6 @@ Section "Uninstall"
|
||||
${EndIf}
|
||||
${EndIf}
|
||||
|
||||
${un.IsVista} $R9
|
||||
${If} $R9 == "true"
|
||||
DeleteRegValue HKLM "Software\RegisteredApplications" "${DDEApplication}"
|
||||
${EndIf}
|
||||
|
||||
; Remove files. If we don't have a log file skip
|
||||
${If} ${FileExists} "$INSTDIR\uninstall\uninstall.log"
|
||||
; Copy the uninstall log file to a temporary file
|
||||
@@ -380,7 +393,6 @@ Function un.preInstFiles
|
||||
ClearErrors
|
||||
${un.CloseApp} "true" $(WARN_APP_RUNNING_UNINSTALL)
|
||||
ClearErrors
|
||||
; Try one more time and if that fails uninstall what ever we are able to.
|
||||
${DeleteFile} "$INSTDIR\${FileMainEXE}"
|
||||
${EndIf}
|
||||
${EndIf}
|
||||
@@ -426,61 +438,57 @@ Function .onInit
|
||||
${EndUnless}
|
||||
${GetParameters} $R0
|
||||
|
||||
StrCpy $R1 "Software\Clients\StartMenuInternet\${FileMainEXE}\InstallInfo"
|
||||
SetShellVarContext all ; Set $DESKTOP to All Users
|
||||
|
||||
; Hide icons - initiated from Set Program Access and Defaults
|
||||
${If} $R0 == "/HideShortcuts"
|
||||
WriteRegDWORD HKLM $R1 "IconsVisible" 0
|
||||
${Unless} ${FileExists} "$DESKTOP\${BrandFullName}.lnk"
|
||||
SetShellVarContext current ; Set $DESKTOP to the current user's desktop
|
||||
${EndUnless}
|
||||
|
||||
${If} ${FileExists} "$DESKTOP\${BrandFullName}.lnk"
|
||||
ShellLink::GetShortCutArgs "$DESKTOP\${BrandFullName}.lnk"
|
||||
Pop $0
|
||||
${If} $0 == ""
|
||||
ShellLink::GetShortCutTarget "$DESKTOP\${BrandFullName}.lnk"
|
||||
Pop $0
|
||||
${If} $0 == "$INSTDIR\${FileMainEXE}"
|
||||
Delete "$DESKTOP\${BrandFullName}.lnk"
|
||||
${EndIf}
|
||||
${EndIf}
|
||||
${EndIf}
|
||||
|
||||
${If} ${FileExists} "$QUICKLAUNCH\${BrandFullName}.lnk"
|
||||
ShellLink::GetShortCutArgs "$QUICKLAUNCH\${BrandFullName}.lnk"
|
||||
Pop $0
|
||||
${If} $0 == ""
|
||||
ShellLink::GetShortCutTarget "$QUICKLAUNCH\${BrandFullName}.lnk"
|
||||
Pop $0
|
||||
${If} $0 == "$INSTDIR\${FileMainEXE}"
|
||||
Delete "$QUICKLAUNCH\${BrandFullName}.lnk"
|
||||
${EndIf}
|
||||
${EndIf}
|
||||
${EndIf}
|
||||
Abort
|
||||
${EndIf}
|
||||
|
||||
; Show icons - initiated from Set Program Access and Defaults
|
||||
${If} $R0 == "/ShowShortcuts"
|
||||
WriteRegDWORD HKLM $R1 "IconsVisible" 1
|
||||
${Unless} ${FileExists} "$DESKTOP\${BrandFullName}.lnk"
|
||||
CreateShortCut "$DESKTOP\${BrandFullName}.lnk" "$INSTDIR\${FileMainEXE}" "" "$INSTDIR\${FileMainEXE}" 0
|
||||
ShellLink::SetShortCutWorkingDirectory "$DESKTOP\${BrandFullName}.lnk" "$INSTDIR"
|
||||
${Unless} ${FileExists} "$DESKTOP\${BrandFullName}.lnk"
|
||||
SetShellVarContext current ; Set $DESKTOP to the current user's desktop
|
||||
${Unless} ${FileExists} "$DESKTOP\${BrandFullName}.lnk"
|
||||
CreateShortCut "$DESKTOP\${BrandFullName}.lnk" "$INSTDIR\${FileMainEXE}" "" "$INSTDIR\${FileMainEXE}" 0
|
||||
ShellLink::SetShortCutWorkingDirectory "$DESKTOP\${BrandFullName}.lnk" "$INSTDIR"
|
||||
${Switch} $R0
|
||||
${Case} "/HideShortcuts"
|
||||
${HideShortcuts}
|
||||
StrCpy $R1 "true"
|
||||
${Break}
|
||||
${Case} "/ShowShortcuts"
|
||||
${ShowShortcuts}
|
||||
StrCpy $R1 "true"
|
||||
${Break}
|
||||
${Case} "/SetAsDefaultAppUser"
|
||||
${SetAsDefaultAppUser}
|
||||
StrCpy $R1 "true"
|
||||
${Break}
|
||||
${Case} "/SetAsDefaultAppGlobal"
|
||||
${SetAsDefaultAppGlobal}
|
||||
StrCpy $R1 "true"
|
||||
${Break}
|
||||
${Default}
|
||||
ClearErrors
|
||||
${Unless} "$R0" == ""
|
||||
${WordReplace} "$R0" "$\"" "" "+" $R0
|
||||
ClearErrors
|
||||
${GetOptions} "$R0" "/PostUpdate" $R2
|
||||
${Unless} ${Errors}
|
||||
${PostUpdate}
|
||||
ClearErrors
|
||||
${GetOptions} "$R0" "/UninstallLog=" $R2
|
||||
${Unless} ${Errors}
|
||||
${Unless} "$R2" == ""
|
||||
GetFullPathName $R3 "$R2"
|
||||
${If} ${FileExists} "$R3"
|
||||
Delete "$INSTDIR\uninstall\*wizard*"
|
||||
Delete "$INSTDIR\uninstall\uninstall.log"
|
||||
CopyFiles /SILENT "$R3" "$INSTDIR\uninstall\"
|
||||
Push $R3
|
||||
${GetParentDir}
|
||||
Pop $R4
|
||||
Delete "$R3"
|
||||
RmDir "$R4"
|
||||
${EndIf}
|
||||
${EndUnless}
|
||||
${EndUnless}
|
||||
StrCpy $R1 "true"
|
||||
${EndUnless}
|
||||
${EndUnless}
|
||||
${EndUnless}
|
||||
${Unless} ${FileExists} "$QUICKLAUNCH\${BrandFullName}.lnk"
|
||||
CreateShortCut "$QUICKLAUNCH\${BrandFullName}.lnk" "$INSTDIR\${FileMainEXE}" "" "$INSTDIR\${FileMainEXE}" 0
|
||||
ShellLink::SetShortCutWorkingDirectory "$QUICKLAUNCH\${BrandFullName}.lnk" "$INSTDIR"
|
||||
${EndUnless}
|
||||
Abort
|
||||
${Break}
|
||||
${EndSwitch}
|
||||
|
||||
${If} $R1 == "true"
|
||||
System::Call "shell32::SHChangeNotify(i, i, i, i) v (0x08000000, 0, 0, 0)"
|
||||
Quit
|
||||
${EndIf}
|
||||
|
||||
; If we made it this far then this installer is being used as an uninstaller.
|
||||
|
||||
@@ -24,7 +24,7 @@ bin\defaults\profile\prefs.js
|
||||
bin\defaults\profile\search.rdf
|
||||
bin\defaults\profile\mimeTypes.rdf
|
||||
bin\defaults\profile\chrome\*
|
||||
bin\uninstall\uninst.exe
|
||||
bin\uninstall\helper.exe
|
||||
bin\updater.ini
|
||||
bin\dictionaries\*
|
||||
|
||||
|
||||
@@ -193,7 +193,7 @@ endif
|
||||
$(MAKE) -C ../installer/windows CONFIG_DIR=l10ngen l10ngen/setup.exe l10ngen/7zSD.sfx
|
||||
cp ../installer/windows/l10ngen/setup.exe l10n-stage
|
||||
$(NSINSTALL) -D l10n-stage/localized/uninstall
|
||||
cp ../installer/windows/l10ngen/uninst.exe l10n-stage/localized/uninstall
|
||||
cp ../installer/windows/l10ngen/helper.exe l10n-stage/localized/uninstall
|
||||
rm -f app.7z
|
||||
cd l10n-stage && \
|
||||
$(CYGWIN_WRAPPER) 7z a -r -t7z ../app.7z -mx -m0=BCJ2 -m1=LZMA:d24 -m2=LZMA:d19 -m3=LZMA:d19 -mb0:1 -mb0s1:2 -mb0s2:3
|
||||
@@ -232,7 +232,7 @@ repackage-zip: $(ZIP_IN)
|
||||
ifeq (WINNT,$(OS_ARCH))
|
||||
$(RM) -r $(STAGEDIST)/uninstall
|
||||
$(NSINSTALL) -D $(STAGEDIST)/uninstall
|
||||
cp ../installer/windows/l10ngen/uninst.exe $(STAGEDIST)/uninstall
|
||||
cp ../installer/windows/l10ngen/helper.exe $(STAGEDIST)/uninstall
|
||||
endif
|
||||
$(RM) -r $(DIST)/xpi-stage/locale-$(AB_CD)/chrome/$(AB_CD)
|
||||
cd $(DIST)/xpi-stage/locale-$(AB_CD) && \
|
||||
|
||||
@@ -55,7 +55,8 @@ DOMI_TITLE=DOM Inspector
|
||||
DOMI_TEXT=Inspects the structure and properties of a window and its contents.
|
||||
QFA_TITLE=Quality Feedback Agent
|
||||
QFA_TEXT=Sends information about program crashes to Mozilla.
|
||||
OPTIONS=$(^NameDA) &Options
|
||||
CONTEXT_OPTIONS=${BrandShortName} &Options
|
||||
CONTEXT_SAFE_MODE=${BrandShortName} &Safe Mode
|
||||
SAFE_MODE=Safe Mode
|
||||
OPTIONS_PAGE_TITLE=Setup Type
|
||||
OPTIONS_PAGE_SUBTITLE=Choose setup options
|
||||
|
||||
@@ -91,6 +91,8 @@ Var fhUninstallLog
|
||||
!include locales.nsi
|
||||
!include version.nsh
|
||||
|
||||
VIAddVersionKey "FileDescription" "${BrandShortName} Installer"
|
||||
|
||||
!insertmacro RegCleanMain
|
||||
!insertmacro RegCleanUninstall
|
||||
!insertmacro CloseApp
|
||||
|
||||
@@ -70,6 +70,10 @@ Var TmpVal
|
||||
!include locales.nsi
|
||||
!include version.nsh
|
||||
|
||||
; This is named BrandShortName helper because we use this for software update
|
||||
; post update cleanup.
|
||||
VIAddVersionKey "FileDescription" "${BrandShortName} Helper"
|
||||
|
||||
!insertmacro un.RegCleanMain
|
||||
!insertmacro un.RegCleanUninstall
|
||||
!insertmacro un.CloseApp
|
||||
|
||||
@@ -92,6 +92,8 @@ Var ShortPathNameToExe
|
||||
!include locales.nsi
|
||||
!include version.nsh
|
||||
|
||||
VIAddVersionKey "FileDescription" "${BrandShortName} Installer"
|
||||
|
||||
!insertmacro RegCleanMain
|
||||
!insertmacro RegCleanUninstall
|
||||
!insertmacro CloseApp
|
||||
|
||||
@@ -71,6 +71,10 @@ Var TmpVal
|
||||
!include locales.nsi
|
||||
!include version.nsh
|
||||
|
||||
; This is named BrandShortName helper because we use this for software update
|
||||
; post update cleanup.
|
||||
VIAddVersionKey "FileDescription" "${BrandShortName} Helper"
|
||||
|
||||
!insertmacro un.RegCleanMain
|
||||
!insertmacro un.RegCleanUninstall
|
||||
!insertmacro un.CloseApp
|
||||
|
||||
@@ -530,87 +530,6 @@ Exch $R9 ; exchange the new $R9 value with the top of the stack
|
||||
!verbose pop
|
||||
!macroend
|
||||
|
||||
/**
|
||||
* Checks whether the system is running Vista. If the system is running Vista
|
||||
* this will return true... if not, this will return false.
|
||||
*
|
||||
* IMPORTANT! $R9 will be overwritten by this macro with the return value so
|
||||
* protect yourself!
|
||||
*
|
||||
* @return _RESULT
|
||||
* true if the system is running Vista otherwise false.
|
||||
*
|
||||
* $R7 = value of CurrentVersion from call to ReadRegStr
|
||||
* $R8 = leftmost char from $R7 used for comparison. If this is 6 then the
|
||||
* system is running Vista.
|
||||
* $R9 = _RESULT
|
||||
*/
|
||||
!macro IsVista
|
||||
|
||||
!ifndef ${_MOZFUNC_UN}IsVista
|
||||
!verbose push
|
||||
!verbose ${_MOZFUNC_VERBOSE}
|
||||
!define ${_MOZFUNC_UN}IsVista "!insertmacro ${_MOZFUNC_UN}IsVistaCall"
|
||||
|
||||
Function ${_MOZFUNC_UN}IsVista
|
||||
Push $R7
|
||||
Push $R8
|
||||
|
||||
StrCpy $R9 "false"
|
||||
|
||||
ClearErrors
|
||||
|
||||
ReadRegStr $R7 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion" CurrentVersion
|
||||
IfErrors end 0
|
||||
|
||||
StrCpy $R8 $R7 1
|
||||
StrCmp $R8 "6" 0 end
|
||||
StrCpy $R9 "true"
|
||||
|
||||
end:
|
||||
|
||||
ClearErrors
|
||||
|
||||
Pop $R8
|
||||
Pop $R7
|
||||
Push $R9
|
||||
FunctionEnd
|
||||
|
||||
!verbose pop
|
||||
!endif
|
||||
!macroend
|
||||
|
||||
!macro IsVistaCall _RESULT
|
||||
!verbose push
|
||||
!verbose ${_MOZFUNC_VERBOSE}
|
||||
Call IsVista
|
||||
Pop ${_RESULT}
|
||||
!verbose pop
|
||||
!macroend
|
||||
|
||||
!macro un.IsVistaCall _RESULT
|
||||
!verbose push
|
||||
!verbose ${_MOZFUNC_VERBOSE}
|
||||
Call un.IsVista
|
||||
Pop ${_RESULT}
|
||||
!verbose pop
|
||||
!macroend
|
||||
|
||||
!macro un.IsVista
|
||||
!ifndef un.IsVista
|
||||
!verbose push
|
||||
!verbose ${_MOZFUNC_VERBOSE}
|
||||
!undef _MOZFUNC_UN
|
||||
!define _MOZFUNC_UN "un."
|
||||
|
||||
!insertmacro IsVista
|
||||
|
||||
!undef _MOZFUNC_UN
|
||||
!define _MOZFUNC_UN
|
||||
!verbose pop
|
||||
!endif
|
||||
!macroend
|
||||
|
||||
/**
|
||||
* Checks whether we can write to the install directory. If the install
|
||||
* directory already exists this will attempt to create a temporary file in the
|
||||
@@ -1190,12 +1109,15 @@ Exch $R9 ; exchange the new $R9 value with the top of the stack
|
||||
|
||||
ClearErrors
|
||||
WriteRegStr SHCTX "$R6" "$R7" "$R8"
|
||||
|
||||
!ifndef NO_LOG
|
||||
IfErrors 0 +3
|
||||
FileWrite $fhInstallLog " ** ERROR Adding Registry String: $R5 | $R6 | $R7 | $R8 **$\r$\n"
|
||||
GoTo +4
|
||||
IntCmp $R9 1 0 +2
|
||||
FileWrite $fhUninstallLog "RegVal: $R5 | $R6 | $R7$\r$\n"
|
||||
FileWrite $fhInstallLog " Added Registry String: $R5 | $R6 | $R7 | $R8$\r$\n"
|
||||
!endif
|
||||
|
||||
Exch $R5
|
||||
Exch 4
|
||||
@@ -1292,12 +1214,14 @@ Exch $R9 ; exchange the new $R9 value with the top of the stack
|
||||
|
||||
ClearErrors
|
||||
WriteRegDWORD SHCTX "$R6" "$R7" "$R8"
|
||||
!ifndef NO_LOG
|
||||
IfErrors 0 +3
|
||||
FileWrite $fhInstallLog " ** ERROR Adding Registry DWord: $R5 | $R6 | $R7 | $R8 **$\r$\n"
|
||||
GoTo +4
|
||||
IntCmp $R5 1 0 +2
|
||||
FileWrite $fhUninstallLog "RegVal: $R5 | $R6 | $R7$\r$\n"
|
||||
FileWrite $fhInstallLog " Added Registry DWord: $R5 | $R6 | $R7 | $R8$\r$\n"
|
||||
!endif
|
||||
|
||||
Exch $R5
|
||||
Exch 4
|
||||
@@ -1394,12 +1318,15 @@ Exch $R9 ; exchange the new $R9 value with the top of the stack
|
||||
|
||||
ClearErrors
|
||||
WriteRegStr HKCR "$R6" "$R7" "$R8"
|
||||
|
||||
!ifndef NO_LOG
|
||||
IfErrors 0 +3
|
||||
FileWrite $fhInstallLog " ** ERROR Adding Registry String: $R5 | $R6 | $R7 | $R8 **$\r$\n"
|
||||
GoTo +4
|
||||
IntCmp $R5 1 0 +2
|
||||
FileWrite $fhUninstallLog "RegVal: $R5 | $R6 | $R7$\r$\n"
|
||||
FileWrite $fhInstallLog " Added Registry String: $R5 | $R6 | $R7 | $R8$\r$\n"
|
||||
!endif
|
||||
|
||||
Exch $R5
|
||||
Exch 4
|
||||
@@ -1515,6 +1442,7 @@ Exch $R9 ; exchange the new $R9 value with the top of the stack
|
||||
; see definition of RegCreateKey
|
||||
System::Call "${RegCreateKey}($R6, '$R8', .r14) .r15"
|
||||
|
||||
!ifndef NO_LOG
|
||||
; if $R5 is not 0 then there was an error creating the registry key.
|
||||
IntCmp $R5 0 +3
|
||||
FileWrite $fhInstallLog " ** ERROR Adding Registry Key: $R7 | $R8 **$\r$\n"
|
||||
@@ -1522,6 +1450,7 @@ Exch $R9 ; exchange the new $R9 value with the top of the stack
|
||||
IntCmp $R9 1 0 +2
|
||||
FileWrite $fhUninstallLog "RegKey: $R7 | $R8$\r$\n"
|
||||
FileWrite $fhInstallLog " Added Registry Key: $R7 | $R8$\r$\n"
|
||||
!endif
|
||||
|
||||
Pop $R4
|
||||
Pop $R5
|
||||
@@ -1572,114 +1501,6 @@ Exch $R9 ; exchange the new $R9 value with the top of the stack
|
||||
!endif
|
||||
!macroend
|
||||
|
||||
/**
|
||||
* Finds an installation of the application so we can force an install into an
|
||||
* existing location for Vista. This uses SHCTX to determine the
|
||||
* registry hive so you must call SetShellVarContext first.
|
||||
*
|
||||
* IMPORTANT! $R9 will be overwritten by this macro with the return value so
|
||||
* protect yourself!
|
||||
*
|
||||
* @param _KEY
|
||||
* The registry subkey (typically this will be Software\Mozilla).
|
||||
* @return _RESULT
|
||||
* false if an install isn't found, path to the main exe if an install
|
||||
* is found.
|
||||
*
|
||||
* $R3 = _KEY
|
||||
* $R4 = value returned from the outer loop's EnumRegKey
|
||||
* $R5 = value returned from ReadRegStr
|
||||
* $R6 = counter for the outer loop's EnumRegKey
|
||||
* $R7 = value returned popped from the stack for GetPathFromRegStr macro
|
||||
* $R8 = value returned popped from the stack for GetParentDir macro
|
||||
* $R9 = _RESULT
|
||||
*/
|
||||
!macro GetExistingInstallPath
|
||||
|
||||
!ifndef ${_MOZFUNC_UN}GetExistingInstallPath
|
||||
!verbose push
|
||||
!verbose ${_MOZFUNC_VERBOSE}
|
||||
!define ${_MOZFUNC_UN}GetExistingInstallPath "!insertmacro ${_MOZFUNC_UN}GetExistingInstallPathCall"
|
||||
|
||||
Function ${_MOZFUNC_UN}GetExistingInstallPath
|
||||
Exch $R3
|
||||
Push $R4
|
||||
Push $R5
|
||||
Push $R6
|
||||
Push $R7
|
||||
Push $R8
|
||||
|
||||
StrCpy $R9 "false"
|
||||
StrCpy $R6 0 ; set the counter for the loop to 0
|
||||
|
||||
loop:
|
||||
EnumRegKey $R4 SHCTX $R3 $R6
|
||||
StrCmp $R4 "" end ; if empty there are no more keys to enumerate
|
||||
IntOp $R6 $R6 + 1 ; increment the loop's counter
|
||||
ClearErrors
|
||||
ReadRegStr $R5 SHCTX "$R3\$R4\bin" "PathToExe"
|
||||
IfErrors loop
|
||||
Push $R5
|
||||
${GetPathFromRegStr}
|
||||
Pop $R7
|
||||
|
||||
IfFileExists "$R7" 0 +5
|
||||
Push "$R7"
|
||||
${GetParent} "$R7" $R8
|
||||
StrCpy $R9 "$R8"
|
||||
GoTo end
|
||||
|
||||
GoTo loop
|
||||
|
||||
end:
|
||||
ClearErrors
|
||||
|
||||
Pop $R8
|
||||
Pop $R7
|
||||
Pop $R6
|
||||
Pop $R5
|
||||
Pop $R4
|
||||
Exch $R3
|
||||
Push $R9
|
||||
FunctionEnd
|
||||
|
||||
!verbose pop
|
||||
!endif
|
||||
!macroend
|
||||
|
||||
!macro GetExistingInstallPathCall _KEY _RESULT
|
||||
!verbose push
|
||||
!verbose ${_MOZFUNC_VERBOSE}
|
||||
Push "${_KEY}"
|
||||
Call GetExistingInstallPath
|
||||
Pop ${_RESULT}
|
||||
!verbose pop
|
||||
!macroend
|
||||
|
||||
!macro un.GetExistingInstallPathCall _KEY _RESULT
|
||||
!verbose push
|
||||
!verbose ${_MOZFUNC_VERBOSE}
|
||||
Push "${_KEY}"
|
||||
Call un.GetExistingInstallPath
|
||||
Pop ${_RESULT}
|
||||
!verbose pop
|
||||
!macroend
|
||||
|
||||
!macro un.GetExistingInstallPath
|
||||
!ifndef un.GetExistingInstallPath
|
||||
!verbose push
|
||||
!verbose ${_MOZFUNC_VERBOSE}
|
||||
!undef _MOZFUNC_UN
|
||||
!define _MOZFUNC_UN "un."
|
||||
|
||||
!insertmacro GetExistingInstallPath
|
||||
|
||||
!undef _MOZFUNC_UN
|
||||
!define _MOZFUNC_UN
|
||||
!verbose pop
|
||||
!endif
|
||||
!macroend
|
||||
|
||||
/**
|
||||
* Finds a second installation of the application so we can make informed
|
||||
* decisions about registry operations. This uses SHCTX to determine the
|
||||
@@ -1791,6 +1612,137 @@ Exch $R9 ; exchange the new $R9 value with the top of the stack
|
||||
!endif
|
||||
!macroend
|
||||
|
||||
/**
|
||||
* Writes common registry values for a handler using SHCTX.
|
||||
* @param _KEY
|
||||
* The subkey in relation to the key root.
|
||||
* @param _VALOPEN
|
||||
* The path and args to launch the application.
|
||||
* @param _VALICON
|
||||
* The path to an exe that contains an icon and the icon resource id.
|
||||
* @param _DISPNAME
|
||||
* The display name for the handler. If emtpy no value will be set.
|
||||
* @param _ISPROTOCOL
|
||||
* Sets protocol handler specific registry values when "true".
|
||||
* @param _ISDDE
|
||||
* Sets DDE specific registry values when "true".
|
||||
*
|
||||
* $R3 = string value of the current registry key path.
|
||||
* $R4 = _KEY
|
||||
* $R5 = _VALOPEN
|
||||
* $R6 = _VALICON
|
||||
* $R7 = _DISPNAME
|
||||
* $R8 = _ISPROTOCOL
|
||||
* $R9 = _ISDDE
|
||||
*/
|
||||
!macro AddHandlerValues
|
||||
|
||||
!ifndef ${_MOZFUNC_UN}AddHandlerValues
|
||||
!verbose push
|
||||
!verbose ${_MOZFUNC_VERBOSE}
|
||||
!define ${_MOZFUNC_UN}AddHandlerValues "!insertmacro ${_MOZFUNC_UN}AddHandlerValuesCall"
|
||||
|
||||
Function ${_MOZFUNC_UN}AddHandlerValues
|
||||
Exch $R9
|
||||
Exch 1
|
||||
Exch $R8
|
||||
Exch 2
|
||||
Exch $R7
|
||||
Exch 3
|
||||
Exch $R6
|
||||
Exch 4
|
||||
Exch $R5
|
||||
Exch 5
|
||||
Exch $R4
|
||||
Push $R3
|
||||
|
||||
StrCmp "$R7" "" +6 0
|
||||
ReadRegStr $R3 SHCTX "$R4" "FriendlyTypeName"
|
||||
|
||||
StrCmp "$R3" "" 0 +3
|
||||
WriteRegStr SHCTX "$R4" "" "$R7"
|
||||
WriteRegStr SHCTX "$R4" "FriendlyTypeName" "$R7"
|
||||
|
||||
StrCmp "$R8" "true" 0 +4
|
||||
DeleteRegValue SHCTX "$R4" "EditFlags"
|
||||
WriteRegBin SHCTX "$R4" "EditFlags" 2
|
||||
WriteRegStr SHCTX "$R4" "URL Protocol" ""
|
||||
|
||||
StrCmp "$R9" "true" 0 +13
|
||||
WriteRegStr SHCTX "$R4\DefaultIcon" "" "$R6"
|
||||
WriteRegStr SHCTX "$R4\shell\open\command" "" "$R5"
|
||||
WriteRegStr SHCTX "$R4\shell\open\ddeexec" "" "$\"%1$\",,0,0,,,,"
|
||||
WriteRegStr SHCTX "$R4\shell\open\ddeexec" "NoActivateHandler" ""
|
||||
WriteRegStr SHCTX "$R4\shell\open\ddeexec\Application" "" "${DDEApplication}"
|
||||
WriteRegStr SHCTX "$R4\shell\open\ddeexec\Topic" "" "WWW_OpenURL"
|
||||
; The ifexec key may have been added by another application so try to
|
||||
; delete it to prevent it from breaking this app's shell integration.
|
||||
; Also, IE 6 and below doesn't remove this key when it sets itself as the
|
||||
; default handler and if this key exists IE's shell integration breaks.
|
||||
DeleteRegKey HKLM "$R4\shell\open\ddeexec\ifexec"
|
||||
DeleteRegKey HKCU "$R4\shell\open\ddeexec\ifexec"
|
||||
|
||||
ClearErrors
|
||||
|
||||
Pop $R3
|
||||
Exch $R4
|
||||
Exch 5
|
||||
Exch $R5
|
||||
Exch 4
|
||||
Exch $R6
|
||||
Exch 3
|
||||
Exch $R7
|
||||
Exch 2
|
||||
Exch $R8
|
||||
Exch 1
|
||||
Exch $R9
|
||||
FunctionEnd
|
||||
|
||||
!verbose pop
|
||||
!endif
|
||||
!macroend
|
||||
|
||||
!macro AddHandlerValuesCall _KEY _VALOPEN _VALICON _DISPNAME _ISPROTOCOL _ISDDE
|
||||
!verbose push
|
||||
!verbose ${_MOZFUNC_VERBOSE}
|
||||
Push "${_KEY}"
|
||||
Push "${_VALOPEN}"
|
||||
Push "${_VALICON}"
|
||||
Push "${_DISPNAME}"
|
||||
Push "${_ISPROTOCOL}"
|
||||
Push "${_ISDDE}"
|
||||
Call AddHandlerValues
|
||||
!verbose pop
|
||||
!macroend
|
||||
|
||||
!macro un.AddHandlerValuesCall _KEY _VALOPEN _VALICON _DISPNAME _ISPROTOCOL _ISDDE
|
||||
!verbose push
|
||||
!verbose ${_MOZFUNC_VERBOSE}
|
||||
Push "${_KEY}"
|
||||
Push "${_VALOPEN}"
|
||||
Push "${_VALICON}"
|
||||
Push "${_DISPNAME}"
|
||||
Push "${_ISPROTOCOL}"
|
||||
Push "${_ISDDE}"
|
||||
Call un.AddHandlerValues
|
||||
!verbose pop
|
||||
!macroend
|
||||
|
||||
!macro un.AddHandlerValues
|
||||
!ifndef un.AddHandlerValues
|
||||
!verbose push
|
||||
!verbose ${_MOZFUNC_VERBOSE}
|
||||
!undef _MOZFUNC_UN
|
||||
!define _MOZFUNC_UN "un."
|
||||
|
||||
!insertmacro AddHandlerValues
|
||||
|
||||
!undef _MOZFUNC_UN
|
||||
!define _MOZFUNC_UN
|
||||
!verbose pop
|
||||
!endif
|
||||
!macroend
|
||||
|
||||
/**
|
||||
* Displays a error message when a file can't be copied.
|
||||
*
|
||||
|
||||
@@ -80,4 +80,8 @@ uninstaller::
|
||||
$(INSTALL) $(topsrcdir)/toolkit/mozapps/installer/windows/nsis/setup.ico $(CONFIG_DIR)
|
||||
cd $(CONFIG_DIR) && makensis.exe uninstaller.nsi
|
||||
$(NSINSTALL) -D $(DIST)/bin/uninstall
|
||||
ifdef MOZ_PHOENIX
|
||||
cp $(CONFIG_DIR)/helper.exe $(DIST)/bin/uninstall
|
||||
else
|
||||
cp $(CONFIG_DIR)/uninst.exe $(DIST)/bin/uninstall
|
||||
endif
|
||||
|
||||
@@ -12,6 +12,5 @@ VIAddVersionKey "ProductName" "${BrandShortName}"
|
||||
VIAddVersionKey "CompanyName" "${CompanyName}"
|
||||
VIAddVersionKey "LegalTrademarks" "${BrandShortName} is a Trademark of The Mozilla Foundation."
|
||||
VIAddVersionKey "LegalCopyright" "${CompanyName}"
|
||||
VIAddVersionKey "FileDescription" "${BrandShortName} Installer"
|
||||
VIAddVersionKey "FileVersion" "${AppVersion}"
|
||||
;VIAddVersionKey "Comments" "Comments"
|
||||
|
||||
@@ -73,7 +73,7 @@ var gLogEnabled = { };
|
||||
* The string to write to the error console..
|
||||
*/
|
||||
function LOG(module, string) {
|
||||
if (module in gLogEnabled) {
|
||||
if (module in gLogEnabled || "all" in gLogEnabled) {
|
||||
dump("*** " + module + ":" + string + "\n");
|
||||
gConsole.logStringMessage(string);
|
||||
}
|
||||
|
||||
@@ -43,12 +43,12 @@
|
||||
*/
|
||||
|
||||
const URI_BRAND_PROPERTIES = "chrome://branding/locale/brand.properties";
|
||||
const URI_UNINSTALL_PROPERTIES = "chrome://branding/content/uninstall.properties";
|
||||
|
||||
const KEY_APPDIR = "XCurProcD";
|
||||
const KEY_COMPONENTS_DIR = "ComsD";
|
||||
const KEY_PLUGINS_DIR = "APlugns";
|
||||
const KEY_EXECUTABLE_FILE = "XREExeF";
|
||||
const KEY_TMPDIR = "TmpD";
|
||||
const KEY_LOCALDATA = "DefProfLRt";
|
||||
const KEY_PROGRAMFILES = "ProgF";
|
||||
const KEY_UAPPDATA = "UAppData";
|
||||
|
||||
// see prio.h
|
||||
const PR_RDONLY = 0x01;
|
||||
@@ -56,16 +56,23 @@ const PR_WRONLY = 0x02;
|
||||
const PR_APPEND = 0x10;
|
||||
|
||||
const PERMS_FILE = 0644;
|
||||
const PERMS_DIR = 0700;
|
||||
|
||||
const nsIWindowsRegKey = Components.interfaces.nsIWindowsRegKey;
|
||||
|
||||
var gConsole = null;
|
||||
var gAppUpdateLogPostUpdate = false;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Console logging support
|
||||
*/
|
||||
function LOG(s) {
|
||||
dump("*** PostUpdateWin: " + s + "\n");
|
||||
if (gAppUpdateLogPostUpdate) {
|
||||
dump("*** PostUpdateWin: " + s + "\n");
|
||||
gConsole.logStringMessage(s);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -122,24 +129,6 @@ function openFileOutputStream(file, flags) {
|
||||
return stream;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current value of the locale. It's possible for this preference to
|
||||
* be localized, so we have to do a little extra work here. Similar code
|
||||
* exists in nsHttpHandler.cpp when building the UA string.
|
||||
*/
|
||||
function getLocale() {
|
||||
const prefName = "general.useragent.locale";
|
||||
var prefs =
|
||||
Components.classes["@mozilla.org/preferences-service;1"].
|
||||
getService(Components.interfaces.nsIPrefBranch);
|
||||
try {
|
||||
return prefs.getComplexValue(prefName,
|
||||
Components.interfaces.nsIPrefLocalizedString).data;
|
||||
} catch (e) {}
|
||||
|
||||
return prefs.getCharPref(prefName);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
const PREFIX_FILE = "File: ";
|
||||
@@ -179,20 +168,49 @@ InstallLogWriter.prototype = {
|
||||
* updates/0 directory has already been cleaned out (see bug 311302).
|
||||
*/
|
||||
_getUpdateLogFile: function() {
|
||||
var file = getFile(KEY_APPDIR);
|
||||
file.append("updates");
|
||||
file.append("0");
|
||||
file.append("update.log");
|
||||
if (file.exists())
|
||||
return file;
|
||||
function appendUpdateLogPath(root) {
|
||||
var file = root.clone();
|
||||
file.append("updates");
|
||||
file.append("0");
|
||||
file.append("update.log");
|
||||
if (file.exists())
|
||||
return file;
|
||||
|
||||
file = getFile(KEY_APPDIR);
|
||||
file.append("updates");
|
||||
file.append("last-update.log");
|
||||
if (file.exists())
|
||||
return file;
|
||||
file = root;
|
||||
file.append("updates");
|
||||
file.append("last-update.log");
|
||||
if (file.exists())
|
||||
return file;
|
||||
|
||||
return null;
|
||||
return null;
|
||||
}
|
||||
|
||||
// See the local appdata first if app dir is under Program Files.
|
||||
var file = null;
|
||||
var updRoot = getFile(KEY_APPDIR);
|
||||
var fileLocator = Components.classes["@mozilla.org/file/directory_service;1"]
|
||||
.getService(Components.interfaces.nsIProperties);
|
||||
var programFilesDir = fileLocator.get(KEY_PROGRAMFILES,
|
||||
Components.interfaces.nsILocalFile);
|
||||
if (programFilesDir.contains(updRoot, true)) {
|
||||
var relativePath = updRoot.QueryInterface(Components.interfaces.nsILocalFile).
|
||||
getRelativeDescriptor(programFilesDir);
|
||||
var userLocalDir = fileLocator.get(KEY_LOCALDATA,
|
||||
Components.interfaces.nsILocalFile).parent;
|
||||
updRoot.setRelativeDescriptor(userLocalDir, relativePath);
|
||||
file = appendUpdateLogPath(updRoot);
|
||||
|
||||
// When updating from Fx 2.0.0.1 to 2.0.0.3 (or later) on Vista,
|
||||
// we will have to see also user app data (see bug 351949).
|
||||
if (!file)
|
||||
file = appendUpdateLogPath(getFile(KEY_UAPPDATA));
|
||||
}
|
||||
|
||||
// See the app dir if not found or app dir is out of Program Files.
|
||||
if (!file)
|
||||
file = appendUpdateLogPath(getFile(KEY_APPDIR));
|
||||
|
||||
return file;
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -337,8 +355,27 @@ InstallLogWriter.prototype = {
|
||||
if (newEntries.length == 0)
|
||||
return;
|
||||
|
||||
// since we are not running with elevated privs, we can't write out
|
||||
// the log file (at least, not on Vista). So, write the output to
|
||||
// temp, and then later, we'll pass the file (gCopiedLog) to
|
||||
// the post update clean up process, which can copy it to
|
||||
// the desired location (because it will have elevated privs)
|
||||
gCopiedLog = getFile(KEY_TMPDIR);
|
||||
gCopiedLog.append("uninstall");
|
||||
gCopiedLog.createUnique(gCopiedLog.DIRECTORY_TYPE, PERMS_DIR);
|
||||
if (uninstallLog)
|
||||
uninstallLog.copyTo(gCopiedLog, "uninstall.log");
|
||||
gCopiedLog.append("uninstall.log");
|
||||
|
||||
LOG("uninstallLog = " + uninstallLog.path);
|
||||
LOG("copiedLog = " + gCopiedLog.path);
|
||||
|
||||
if (!gCopiedLog.exists())
|
||||
gCopiedLog.create(Components.interfaces.nsILocalFile.NORMAL_FILE_TYPE,
|
||||
PERMS_FILE);
|
||||
|
||||
this._outputStream =
|
||||
openFileOutputStream(uninstallLog, PR_WRONLY | PR_APPEND);
|
||||
openFileOutputStream(gCopiedLog, PR_WRONLY | PR_APPEND);
|
||||
|
||||
// The NSIS uninstaller deletes all directories where the installer has
|
||||
// added a file if the directory is empty after the files have been removed
|
||||
@@ -356,12 +393,15 @@ InstallLogWriter.prototype = {
|
||||
};
|
||||
|
||||
var installLogWriter;
|
||||
var gCopiedLog;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* A thin wrapper around nsIWindowsRegKey that keeps track of its path
|
||||
* and notifies the installLogWriter when modifications are made.
|
||||
* A thin wrapper around nsIWindowsRegKey
|
||||
* note, only the "read" methods are exposed. If you want to write
|
||||
* to the registry on Vista, you need to be a priveleged app.
|
||||
* We've moved that code into the uninstaller.
|
||||
*/
|
||||
function RegKey() {
|
||||
// Internally, we may pass parameters to this constructor.
|
||||
@@ -381,12 +421,11 @@ RegKey.prototype = {
|
||||
_path: null,
|
||||
|
||||
ACCESS_READ: nsIWindowsRegKey.ACCESS_READ,
|
||||
ACCESS_WRITE: nsIWindowsRegKey.ACCESS_WRITE,
|
||||
ACCESS_ALL: nsIWindowsRegKey.ACCESS_ALL,
|
||||
|
||||
ROOT_KEY_CURRENT_USER: nsIWindowsRegKey.ROOT_KEY_CURRENT_USER,
|
||||
ROOT_KEY_LOCAL_MACHINE: nsIWindowsRegKey.ROOT_KEY_LOCAL_MACHINE,
|
||||
|
||||
ROOT_KEY_CLASSES_ROOT: nsIWindowsRegKey.ROOT_KEY_CLASSES_ROOT,
|
||||
|
||||
close: function() {
|
||||
this._key.close();
|
||||
this._root = null;
|
||||
@@ -404,24 +443,10 @@ RegKey.prototype = {
|
||||
return new RegKey(child, this._root, this._path + "\\" + path);
|
||||
},
|
||||
|
||||
createChild: function(path, mode) {
|
||||
var child = this._key.createChild(path, mode);
|
||||
var key = new RegKey(child, this._root, this._path + "\\" + path);
|
||||
return key;
|
||||
},
|
||||
|
||||
readStringValue: function(name) {
|
||||
return this._key.readStringValue(name);
|
||||
},
|
||||
|
||||
writeStringValue: function(name, value) {
|
||||
this._key.writeStringValue(name, value);
|
||||
},
|
||||
|
||||
writeIntValue: function(name, value) {
|
||||
this._key.writeIntValue(name, value);
|
||||
},
|
||||
|
||||
hasValue: function(name) {
|
||||
return this._key.hasValue(name);
|
||||
},
|
||||
@@ -438,13 +463,12 @@ RegKey.prototype = {
|
||||
return this._key.getChildName(index);
|
||||
},
|
||||
|
||||
removeChild: function(name) {
|
||||
this._key.removeChild(name);
|
||||
},
|
||||
|
||||
toString: function() {
|
||||
var root;
|
||||
switch (this._root) {
|
||||
case this.ROOT_KEY_CLASSES_ROOT:
|
||||
root = "HKEY_KEY_CLASSES_ROOT";
|
||||
break;
|
||||
case this.ROOT_KEY_LOCAL_MACHINE:
|
||||
root = "HKEY_LOCAL_MACHINE";
|
||||
break;
|
||||
@@ -459,86 +483,14 @@ RegKey.prototype = {
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
RegKey.prototype = {
|
||||
// The name of the registry key
|
||||
name: "";
|
||||
|
||||
// An array of strings, where each even-indexed string names a value,
|
||||
// and the subsequent string provides data for the value.
|
||||
values: [];
|
||||
|
||||
// An array of RegKey objects.
|
||||
children: [];
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* This function creates a heirarchy of registry keys. If any of the
|
||||
* keys or values already exist, then they will be updated instead.
|
||||
* @param rootKey
|
||||
* The root registry key from which to create the new registry
|
||||
* keys.
|
||||
* @param data
|
||||
* A JS object with properties: "name", "values", and "children"
|
||||
* as defined above. All children of this key will be created.
|
||||
*/
|
||||
function createRegistryKeys(rootKey, data) {
|
||||
var key;
|
||||
try {
|
||||
key = rootKey.createChild(data.name, rootKey.ACCESS_WRITE);
|
||||
var i;
|
||||
if ("values" in data) {
|
||||
for (i = 0; i < data.values.length; i += 2)
|
||||
key.writeStringValue(data.values[i], data.values[i + 1]);
|
||||
}
|
||||
if ("children" in data) {
|
||||
for (i = 0; i < data.children.length; ++i)
|
||||
createRegistryKeys(key, data.children[i]);
|
||||
}
|
||||
key.close();
|
||||
} catch (e) {
|
||||
LOG(e);
|
||||
if (key)
|
||||
key.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function deletes the specified registry key and optionally all of its
|
||||
* children.
|
||||
* @param rootKey
|
||||
* The parent nsIwindowRegKey of the key to delete.
|
||||
* @param name
|
||||
* The name of the key to delete.
|
||||
* @param recurse
|
||||
* Pass true to also delete all children of the named key. Take care!
|
||||
*/
|
||||
function deleteRegistryKey(rootKey, name, recurse) {
|
||||
if (!rootKey.hasChild(name)) {
|
||||
LOG("deleteRegistryKey: rootKey does not have child: \"" + name + "\"");
|
||||
return;
|
||||
}
|
||||
if (recurse) {
|
||||
var key = rootKey.openChild(name, rootKey.ACCESS_ALL);
|
||||
try {
|
||||
for (var i = key.childCount - 1; i >= 0; --i)
|
||||
deleteRegistryKey(key, key.getChildName(i), true);
|
||||
} finally {
|
||||
key.close();
|
||||
}
|
||||
}
|
||||
rootKey.removeChild(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method walks the registry looking for the registry keys of
|
||||
* the previous version of the application.
|
||||
*/
|
||||
function locateOldInstall(key, ourInstallDir) {
|
||||
var result, childKey, productKey, mainKey;
|
||||
function haveOldInstall(key, brandFullName, version) {
|
||||
var ourInstallDir = getFile(KEY_APPDIR);
|
||||
var result = false;
|
||||
var childKey, productKey, mainKey;
|
||||
try {
|
||||
for (var i = 0; i < key.childCount; ++i) {
|
||||
var childName = key.getChildName(i);
|
||||
@@ -550,14 +502,14 @@ function locateOldInstall(key, ourInstallDir) {
|
||||
if (productKey.hasChild("Main")) {
|
||||
mainKey = productKey.openChild("Main", key.ACCESS_READ);
|
||||
var installDir = mainKey.readStringValue("Install Directory");
|
||||
var menuPath = mainKey.readStringValue("Program Folder Path");
|
||||
mainKey.close();
|
||||
if (newFile(installDir).equals(ourInstallDir)) {
|
||||
result = new Object();
|
||||
result.fullName = childName;
|
||||
result.versionWithLocale = productVer;
|
||||
result.version = productVer.split(" ")[0];
|
||||
result.menuPath = menuPath;
|
||||
LOG("old install? " + installDir + " vs " + ourInstallDir.path);
|
||||
LOG("old install? " + childName + " vs " + brandFullName);
|
||||
LOG("old install? " + productVer.split(" ")[0] + " vs " + version);
|
||||
if (newFile(installDir).equals(ourInstallDir) &&
|
||||
(childName != brandFullName ||
|
||||
productVer.split(" ")[0] != version)) {
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
productKey.close();
|
||||
@@ -570,7 +522,7 @@ function locateOldInstall(key, ourInstallDir) {
|
||||
break;
|
||||
}
|
||||
} catch (e) {
|
||||
result = null;
|
||||
result = false;
|
||||
if (childKey)
|
||||
childKey.close();
|
||||
if (productKey)
|
||||
@@ -581,239 +533,62 @@ function locateOldInstall(key, ourInstallDir) {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete registry keys left-over from the previous version of the app
|
||||
* installed at our location.
|
||||
*/
|
||||
function deleteOldRegKeys(key, info) {
|
||||
deleteRegistryKey(key, info.fullName + " " + info.version, true);
|
||||
var productKey = key.openChild(info.fullName, key.ACCESS_ALL);
|
||||
var productCount;
|
||||
function checkRegistry()
|
||||
{
|
||||
// XXX todo
|
||||
// this is firefox specific
|
||||
// figure out what to do about tbird and sunbird, etc
|
||||
LOG("checkRegistry");
|
||||
|
||||
var result = false;
|
||||
try {
|
||||
deleteRegistryKey(productKey, info.versionWithLocale, true);
|
||||
productCount = productKey.childCount;
|
||||
} finally {
|
||||
productKey.close();
|
||||
var key = new RegKey();
|
||||
key.open(RegKey.prototype.ROOT_KEY_CLASSES_ROOT, "FirefoxHTML\\shell\\open\\command", key.ACCESS_READ);
|
||||
var commandKey = key.readStringValue("");
|
||||
LOG("commandKey = " + commandKey);
|
||||
// if "-requestPending" is not found, we need to do the cleanup
|
||||
result = (commandKey.indexOf("-requestPending") == -1);
|
||||
} catch (e) {
|
||||
LOG("failed to open command key for FirefoxHTML: " + e);
|
||||
}
|
||||
if (productCount == 0)
|
||||
key.removeChild(info.fullName);
|
||||
key.close();
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* The installer sets various registry keys and values that may need to be
|
||||
* updated.
|
||||
*
|
||||
* This operation is a bit tricky since we do not know the previous value of
|
||||
* brandFullName. As a result, we must walk the registry looking for an
|
||||
* existing key that references the same install directory. We assume that
|
||||
* the value of vendorShortName does not change across updates.
|
||||
*/
|
||||
function updateRegistry(rootKey) {
|
||||
LOG("updateRegistry");
|
||||
|
||||
var ourInstallDir = getFile(KEY_APPDIR);
|
||||
|
||||
var app =
|
||||
Components.classes["@mozilla.org/xre/app-info;1"].
|
||||
getService(Components.interfaces.nsIXULAppInfo).
|
||||
QueryInterface(Components.interfaces.nsIXULRuntime);
|
||||
|
||||
var sbs =
|
||||
Components.classes["@mozilla.org/intl/stringbundle;1"].
|
||||
getService(Components.interfaces.nsIStringBundleService);
|
||||
var brandBundle = sbs.createBundle(URI_BRAND_PROPERTIES);
|
||||
var brandFullName = brandBundle.GetStringFromName("brandFullName");
|
||||
|
||||
var vendorShortName;
|
||||
try {
|
||||
// The Thunderbird vendorShortName is "Mozilla Thunderbird", but we
|
||||
// just want "Thunderbird", so allow it to be overridden in prefs.
|
||||
|
||||
var prefs =
|
||||
Components.classes["@mozilla.org/preferences-service;1"].
|
||||
getService(Components.interfaces.nsIPrefBranch);
|
||||
|
||||
vendorShortName = prefs.getCharPref("app.update.vendorName.override");
|
||||
}
|
||||
catch (e) {
|
||||
vendorShortName = brandBundle.GetStringFromName("vendorShortName");
|
||||
}
|
||||
|
||||
function checkOldInstall(rootKey, vendorShortName, brandFullName, version)
|
||||
{
|
||||
var key = new RegKey();
|
||||
var result = false;
|
||||
|
||||
var oldInstall;
|
||||
try {
|
||||
key.open(rootKey, "SOFTWARE\\" + vendorShortName, key.ACCESS_READ);
|
||||
oldInstall = locateOldInstall(key, ourInstallDir);
|
||||
} catch (e) {}
|
||||
key.close();
|
||||
|
||||
if (!oldInstall) {
|
||||
LOG("no existing registry keys found");
|
||||
return;
|
||||
LOG("checkOldInstall: " + key + " " + brandFullName + " " + version);
|
||||
result = haveOldInstall(key, brandFullName, version);
|
||||
} catch (e) {
|
||||
LOG("failed trying to find old install: " + e);
|
||||
}
|
||||
|
||||
const uninstallRoot =
|
||||
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
|
||||
// Maybe nothing needs to be changed...
|
||||
if (oldInstall.fullName == brandFullName &&
|
||||
oldInstall.version == app.version) {
|
||||
var uninst = getFile(KEY_APPDIR);
|
||||
uninst.append("uninstall");
|
||||
uninst.append("uninst.exe");
|
||||
var uninstString = uninst.path;
|
||||
nameWithVersion = oldInstall.fullName + " (" + oldInstall.version + ")";
|
||||
try {
|
||||
key.open(rootKey, uninstallRoot + "\\" + nameWithVersion, key.ACCESS_READ);
|
||||
var regUninstString = key.readStringValue("UninstallString");
|
||||
if (regUninstString != uninstString) {
|
||||
LOG("updating UninstallString registry value");
|
||||
key.close();
|
||||
key.open(rootKey, uninstallRoot, key.ACCESS_READ);
|
||||
createRegistryKeys(key, { name: nameWithVersion,
|
||||
values: ["UninstallString", uninstString] });
|
||||
} else {
|
||||
LOG("registry is up-to-date");
|
||||
}
|
||||
} catch (e) {}
|
||||
key.close();
|
||||
return;
|
||||
}
|
||||
|
||||
// Delete the old keys:
|
||||
try {
|
||||
key.open(rootKey, "SOFTWARE\\" + vendorShortName, key.ACCESS_READ);
|
||||
deleteOldRegKeys(key, oldInstall);
|
||||
} catch (e) {}
|
||||
key.close();
|
||||
|
||||
// Create the new keys:
|
||||
|
||||
var versionWithLocale = app.version + " (" + getLocale() + ")";
|
||||
var installPath = ourInstallDir.path + "\\";
|
||||
var pathToExe = getFile(KEY_EXECUTABLE_FILE).path;
|
||||
|
||||
var Key_bin = {
|
||||
name: "bin",
|
||||
values: [
|
||||
"PathToExe", pathToExe
|
||||
]
|
||||
};
|
||||
var Key_extensions = {
|
||||
name: "Extensions",
|
||||
values: [
|
||||
"Components", getFile(KEY_COMPONENTS_DIR).path + "\\",
|
||||
"Plugins", getFile(KEY_PLUGINS_DIR).path + "\\"
|
||||
]
|
||||
};
|
||||
var Key_nameWithVersion = {
|
||||
name: brandFullName + " " + app.version,
|
||||
values: [
|
||||
"GeckoVer", app.platformVersion
|
||||
],
|
||||
children: [
|
||||
Key_bin,
|
||||
Key_extensions
|
||||
]
|
||||
};
|
||||
var Key_main = {
|
||||
name: "Main",
|
||||
values: [
|
||||
"Install Directory", installPath,
|
||||
"PathToExe", pathToExe,
|
||||
"Program Folder Path", oldInstall.menuPath
|
||||
]
|
||||
};
|
||||
var Key_uninstall = {
|
||||
name: "Uninstall",
|
||||
values: [
|
||||
"Description", brandFullName + " (" + app.version + ")",
|
||||
"Uninstall Log Folder", installPath + "uninstall"
|
||||
]
|
||||
};
|
||||
var Key_versionWithLocale = {
|
||||
name: versionWithLocale,
|
||||
children: [
|
||||
Key_main,
|
||||
Key_uninstall
|
||||
]
|
||||
};
|
||||
var Key_name = {
|
||||
name: brandFullName,
|
||||
values: [
|
||||
"CurrentVersion", versionWithLocale
|
||||
],
|
||||
children: [
|
||||
Key_versionWithLocale
|
||||
]
|
||||
};
|
||||
var Key_brand = {
|
||||
name: vendorShortName,
|
||||
children: [
|
||||
Key_name,
|
||||
Key_nameWithVersion
|
||||
]
|
||||
};
|
||||
|
||||
try {
|
||||
key.open(rootKey, "SOFTWARE", key.ACCESS_READ);
|
||||
createRegistryKeys(key, Key_brand);
|
||||
} catch (e) {}
|
||||
key.close();
|
||||
|
||||
if (rootKey != RegKey.prototype.ROOT_KEY_LOCAL_MACHINE)
|
||||
return;
|
||||
|
||||
// Now, do the same thing for the Add/Remove Programs control panel:
|
||||
try {
|
||||
key.open(rootKey, uninstallRoot, key.ACCESS_READ);
|
||||
var oldName = oldInstall.fullName + " (" + oldInstall.version + ")";
|
||||
deleteRegistryKey(key, oldName, false);
|
||||
} catch (e) {}
|
||||
key.close();
|
||||
|
||||
var uninstallBundle = sbs.createBundle(URI_UNINSTALL_PROPERTIES);
|
||||
|
||||
var nameWithVersion = brandFullName + " (" + app.version + ")";
|
||||
|
||||
var uninstaller = getFile(KEY_APPDIR);
|
||||
uninstaller.append("uninstall");
|
||||
uninstaller.append("uninst.exe");
|
||||
var uninstallString = uninstaller.path;
|
||||
|
||||
Key_uninstall = {
|
||||
name: nameWithVersion,
|
||||
values: [
|
||||
"Comment", brandFullName,
|
||||
"DisplayIcon", pathToExe + ",0", // XXX don't hardcode me!
|
||||
"DisplayName", nameWithVersion,
|
||||
"DisplayVersion", versionWithLocale,
|
||||
"InstallLocation", ourInstallDir.path, // no trailing slash
|
||||
"Publisher", vendorShortName,
|
||||
"UninstallString", uninstallString,
|
||||
"URLInfoAbout", uninstallBundle.GetStringFromName("URLInfoAbout"),
|
||||
"URLUpdateInfo", uninstallBundle.GetStringFromName("URLUpdateInfo")
|
||||
]
|
||||
};
|
||||
|
||||
var child;
|
||||
try {
|
||||
key.open(rootKey, uninstallRoot, key.ACCESS_READ);
|
||||
createRegistryKeys(key, Key_uninstall);
|
||||
|
||||
// Create additional DWORD keys for NoModify and NoRepair:
|
||||
child = key.openChild(nameWithVersion, key.ACCESS_WRITE);
|
||||
child.writeIntValue("NoModify", 1);
|
||||
child.writeIntValue("NoRepair", 1);
|
||||
} catch (e) {}
|
||||
if (child)
|
||||
child.close();
|
||||
key.close();
|
||||
return result;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function nsPostUpdateWin() {
|
||||
gConsole = Components.classes["@mozilla.org/consoleservice;1"]
|
||||
.getService(Components.interfaces.nsIConsoleService);
|
||||
var prefs = Components.classes["@mozilla.org/preferences-service;1"].
|
||||
getService(Components.interfaces.nsIPrefBranch);
|
||||
try {
|
||||
gAppUpdateLogPostUpdate = prefs.getBoolPref("app.update.log.all");
|
||||
}
|
||||
catch (ex) {
|
||||
}
|
||||
try {
|
||||
if (!gAppUpdateLogPostUpdate)
|
||||
gAppUpdateLogPostUpdate = prefs.getBoolPref("app.update.log.PostUpdate");
|
||||
}
|
||||
catch (ex) {
|
||||
}
|
||||
}
|
||||
|
||||
nsPostUpdateWin.prototype = {
|
||||
@@ -826,20 +601,66 @@ nsPostUpdateWin.prototype = {
|
||||
|
||||
run: function() {
|
||||
try {
|
||||
// We use a global object here for the install log writer, so that the
|
||||
// registry updating code can easily inform it of registry keys that it
|
||||
// may create.
|
||||
installLogWriter = new InstallLogWriter();
|
||||
try {
|
||||
installLogWriter.begin();
|
||||
updateRegistry(RegKey.prototype.ROOT_KEY_CURRENT_USER);
|
||||
updateRegistry(RegKey.prototype.ROOT_KEY_LOCAL_MACHINE);
|
||||
} finally {
|
||||
installLogWriter.end();
|
||||
installLogWriter = null;
|
||||
}
|
||||
} catch (e) {
|
||||
LOG(e);
|
||||
}
|
||||
|
||||
var app =
|
||||
Components.classes["@mozilla.org/xre/app-info;1"].
|
||||
getService(Components.interfaces.nsIXULAppInfo).
|
||||
QueryInterface(Components.interfaces.nsIXULRuntime);
|
||||
|
||||
var sbs =
|
||||
Components.classes["@mozilla.org/intl/stringbundle;1"].
|
||||
getService(Components.interfaces.nsIStringBundleService);
|
||||
var brandBundle = sbs.createBundle(URI_BRAND_PROPERTIES);
|
||||
|
||||
var vendorShortName;
|
||||
try {
|
||||
// The Thunderbird vendorShortName is "Mozilla Thunderbird", but we
|
||||
// just want "Thunderbird", so allow it to be overridden in prefs.
|
||||
|
||||
var prefs =
|
||||
Components.classes["@mozilla.org/preferences-service;1"].
|
||||
getService(Components.interfaces.nsIPrefBranch);
|
||||
|
||||
vendorShortName = prefs.getCharPref("app.update.vendorName.override");
|
||||
}
|
||||
catch (e) {
|
||||
vendorShortName = brandBundle.GetStringFromName("vendorShortName");
|
||||
}
|
||||
var brandFullName = brandBundle.GetStringFromName("brandFullName");
|
||||
|
||||
if (!gCopiedLog &&
|
||||
!checkRegistry() &&
|
||||
!checkOldInstall(RegKey.prototype.ROOT_KEY_LOCAL_MACHINE,
|
||||
vendorShortName, brandFullName, app.version) &&
|
||||
!checkOldInstall(RegKey.prototype.ROOT_KEY_CURRENT_USER,
|
||||
vendorShortName, brandFullName, app.version)) {
|
||||
LOG("nothing to do, so don't launch the helper");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
var winAppHelper =
|
||||
app.QueryInterface(Components.interfaces.nsIWinAppHelper);
|
||||
|
||||
// note, gCopiedLog could be null
|
||||
if (gCopiedLog)
|
||||
LOG("calling postUpdate with: " + gCopiedLog.path);
|
||||
else
|
||||
LOG("calling postUpdate without a log");
|
||||
|
||||
winAppHelper.postUpdate(gCopiedLog);
|
||||
} catch (e) {
|
||||
LOG("failed to launch the helper to do the post update cleanup: " + e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -65,6 +65,11 @@ const URI_UPDATES_PROPERTIES = "chrome://mozapps/locale/update/updates.proper
|
||||
const URI_UPDATE_NS = "http://www.mozilla.org/2005/app-update";
|
||||
|
||||
const KEY_APPDIR = "XCurProcD";
|
||||
#ifdef XP_WIN
|
||||
const KEY_LOCALDATA = "DefProfLRt";
|
||||
const KEY_PROGRAMFILES = "ProgF";
|
||||
const KEY_UAPPDATA = "UAppData";
|
||||
#endif
|
||||
|
||||
const DIR_UPDATES = "updates";
|
||||
const FILE_UPDATE_STATUS = "update.status";
|
||||
@@ -180,7 +185,7 @@ function getURLSpecFromFile(file) {
|
||||
* parent directories that need to be created.
|
||||
*/
|
||||
function getDir(key, pathArray) {
|
||||
return getDirInternal(key, pathArray, true);
|
||||
return getDirInternal(key, pathArray, true, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -195,7 +200,21 @@ function getDir(key, pathArray) {
|
||||
* requested does not exist, it is NOT created.
|
||||
*/
|
||||
function getDirNoCreate(key, pathArray) {
|
||||
return getDirInternal(key, pathArray, false);
|
||||
return getDirInternal(key, pathArray, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the specified directory at the specified hierarchy under the
|
||||
* update root directory.
|
||||
* @param pathArray
|
||||
* An array of path components to locate beneath the directory
|
||||
* specified by |key|
|
||||
* @return nsIFile object for the location specified. If the directory
|
||||
* requested does not exist, it is created, along with any
|
||||
* parent directories that need to be created.
|
||||
*/
|
||||
function getUpdateDir(pathArray) {
|
||||
return getDirInternal(KEY_APPDIR, pathArray, true, true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -210,12 +229,27 @@ function getDirNoCreate(key, pathArray) {
|
||||
* true if the directory hierarchy specified in |pathArray|
|
||||
* should be created if it does not exist,
|
||||
* false otherwise.
|
||||
* @param update
|
||||
* true if finding the update directory,
|
||||
* false otherwise.
|
||||
* @return nsIFile object for the location specified.
|
||||
*/
|
||||
function getDirInternal(key, pathArray, shouldCreate) {
|
||||
function getDirInternal(key, pathArray, shouldCreate, update) {
|
||||
var fileLocator = Components.classes["@mozilla.org/file/directory_service;1"]
|
||||
.getService(Components.interfaces.nsIProperties);
|
||||
var dir = fileLocator.get(key, Components.interfaces.nsIFile);
|
||||
var dir = fileLocator.get(key, Components.interfaces.nsILocalFile);
|
||||
#ifdef XP_WIN
|
||||
if (update) {
|
||||
var programFilesDir = fileLocator.get(KEY_PROGRAMFILES,
|
||||
Components.interfaces.nsILocalFile);
|
||||
if (programFilesDir.contains(dir, true)) {
|
||||
var relativePath = dir.getRelativeDescriptor(programFilesDir);
|
||||
var userLocalDir = fileLocator.get(KEY_LOCALDATA,
|
||||
Components.interfaces.nsILocalFile).parent;
|
||||
dir.setRelativeDescriptor(userLocalDir, relativePath);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
for (var i = 0; i < pathArray.length; ++i) {
|
||||
dir.append(pathArray[i]);
|
||||
if (shouldCreate && !dir.exists())
|
||||
@@ -242,6 +276,22 @@ function getFile(key, pathArray) {
|
||||
return file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the file at the speciifed hierarchy under the update root directory.
|
||||
* @param pathArray
|
||||
* An array of path components to locate beneath the directory
|
||||
* specified by |key|. The last item in this array must be the
|
||||
* leaf name of a file.
|
||||
* @return nsIFile object for the file specified. The file is NOT created
|
||||
* if it does not exist, however all required directories along
|
||||
* the way are.
|
||||
*/
|
||||
function getUpdateFile(pathArray) {
|
||||
var file = getUpdateDir(pathArray.slice(0, -1));
|
||||
file.append(pathArray[pathArray.length - 1]);
|
||||
return file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes a Safe Output Stream
|
||||
* @param fos
|
||||
@@ -289,18 +339,36 @@ function getStatusTextFromCode(code, defaultCode) {
|
||||
|
||||
/**
|
||||
* Get the Active Updates directory
|
||||
* @param key
|
||||
* The Directory Service Key (optional).
|
||||
* If used, don't search local appdata on Win32 and don't create dir.
|
||||
* @returns The active updates directory, as a nsIFile object
|
||||
*/
|
||||
function getUpdatesDir() {
|
||||
function getUpdatesDir(key) {
|
||||
// Right now, we only support downloading one patch at a time, so we always
|
||||
// use the same target directory.
|
||||
var fileLocator =
|
||||
Components.classes["@mozilla.org/file/directory_service;1"].
|
||||
getService(Components.interfaces.nsIProperties);
|
||||
var appDir = fileLocator.get(KEY_APPDIR, Components.interfaces.nsIFile);
|
||||
var appDir;
|
||||
if (key)
|
||||
appDir = fileLocator.get(key, Components.interfaces.nsILocalFile);
|
||||
else {
|
||||
appDir = fileLocator.get(KEY_APPDIR, Components.interfaces.nsILocalFile);
|
||||
#ifdef XP_WIN
|
||||
var programFilesDir = fileLocator.get(KEY_PROGRAMFILES,
|
||||
Components.interfaces.nsILocalFile);
|
||||
if (programFilesDir.contains(appDir, true)) {
|
||||
var relativePath = appDir.getRelativeDescriptor(programFilesDir);
|
||||
var userLocalDir = fileLocator.get(KEY_LOCALDATA,
|
||||
Components.interfaces.nsILocalFile).parent;
|
||||
appDir.setRelativeDescriptor(userLocalDir, relativePath);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
appDir.append(DIR_UPDATES);
|
||||
appDir.append("0");
|
||||
if (!appDir.exists())
|
||||
if (!appDir.exists() && !key)
|
||||
appDir.create(nsILocalFile.DIRECTORY_TYPE, PERMS_DIRECTORY);
|
||||
return appDir;
|
||||
}
|
||||
@@ -337,17 +405,20 @@ function writeStatusFile(dir, state) {
|
||||
|
||||
/**
|
||||
* Removes the Updates Directory
|
||||
* @param key
|
||||
* The Directory Service Key under which update directory resides
|
||||
* (optional).
|
||||
*/
|
||||
function cleanUpUpdatesDir() {
|
||||
function cleanUpUpdatesDir(key) {
|
||||
// Bail out if we don't have appropriate permissions
|
||||
var updateDir;
|
||||
try {
|
||||
updateDir = getUpdatesDir();
|
||||
updateDir = getUpdatesDir(key);
|
||||
}
|
||||
catch (e) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var e = updateDir.directoryEntries;
|
||||
while (e.hasMoreElements()) {
|
||||
var f = e.getNext().QueryInterface(Components.interfaces.nsIFile);
|
||||
@@ -386,8 +457,11 @@ function cleanUpUpdatesDir() {
|
||||
|
||||
/**
|
||||
* Clean up updates list and the updates directory.
|
||||
* @param key
|
||||
* The Directory Service Key under which update directory resides
|
||||
* (optional).
|
||||
*/
|
||||
function cleanupActiveUpdate() {
|
||||
function cleanupActiveUpdate(key) {
|
||||
// Move the update from the Active Update list into the Past Updates list.
|
||||
var um =
|
||||
Components.classes["@mozilla.org/updates/update-manager;1"].
|
||||
@@ -396,7 +470,7 @@ function cleanupActiveUpdate() {
|
||||
um.saveUpdates();
|
||||
|
||||
// Now trash the updates directory, since we're done with it
|
||||
cleanUpUpdatesDir();
|
||||
cleanUpUpdatesDir(key);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1048,6 +1122,30 @@ UpdateService.prototype = {
|
||||
if (status == "null")
|
||||
status = null;
|
||||
|
||||
var updRootKey = null;
|
||||
#ifdef XP_WIN
|
||||
function findPreviousUpdate(key) {
|
||||
var updateDir = getUpdatesDir(key);
|
||||
if (updateDir.exists()) {
|
||||
status = readStatusFile(updateDir);
|
||||
// Previous download should succeed. Otherwise, we will not be here!
|
||||
if (status == STATE_SUCCEEDED)
|
||||
updRootKey = key;
|
||||
else
|
||||
status = null;
|
||||
}
|
||||
}
|
||||
|
||||
// required when updating from Fx 2.0.0.1 to 2.0.0.3 (or later)
|
||||
// on Windows Vista.
|
||||
if (status == null)
|
||||
findPreviousUpdate(KEY_UAPPDATA);
|
||||
|
||||
// required to migrate from older versions.
|
||||
if (status == null)
|
||||
findPreviousUpdate(KEY_APPDIR);
|
||||
#endif
|
||||
|
||||
if (status == STATE_DOWNLOADING) {
|
||||
LOG("UpdateService", "_postUpdateProcessing: Downloading patch, resuming...");
|
||||
}
|
||||
@@ -1098,7 +1196,7 @@ UpdateService.prototype = {
|
||||
}
|
||||
|
||||
// Done with this update. Clean it up.
|
||||
cleanupActiveUpdate();
|
||||
cleanupActiveUpdate(updRootKey);
|
||||
}
|
||||
else {
|
||||
// If we hit an error, then the error code will be included in the
|
||||
@@ -1407,7 +1505,7 @@ UpdateService.prototype = {
|
||||
*/
|
||||
get canUpdate() {
|
||||
try {
|
||||
var appDirFile = getFile(KEY_APPDIR, [FILE_PERMS_TEST]);
|
||||
var appDirFile = getUpdateFile([FILE_PERMS_TEST]);
|
||||
if (!appDirFile.exists()) {
|
||||
appDirFile.create(nsILocalFile.NORMAL_FILE_TYPE, PERMS_FILE);
|
||||
appDirFile.remove(false);
|
||||
@@ -1516,8 +1614,7 @@ UpdateService.prototype = {
|
||||
*/
|
||||
function UpdateManager() {
|
||||
// Ensure the Active Update file is loaded
|
||||
var updates = this._loadXMLFileIntoArray(getFile(KEY_APPDIR,
|
||||
[FILE_UPDATE_ACTIVE]));
|
||||
var updates = this._loadXMLFileIntoArray(getUpdateFile([FILE_UPDATE_ACTIVE]));
|
||||
if (updates.length > 0)
|
||||
this._activeUpdate = updates[0];
|
||||
}
|
||||
@@ -1584,7 +1681,7 @@ UpdateManager.prototype = {
|
||||
*/
|
||||
_ensureUpdates: function() {
|
||||
if (!this._updates) {
|
||||
this._updates = this._loadXMLFileIntoArray(getFile(KEY_APPDIR,
|
||||
this._updates = this._loadXMLFileIntoArray(getUpdateFile(
|
||||
[FILE_UPDATES_DB]));
|
||||
|
||||
// Make sure that any active update is part of our updates list
|
||||
@@ -1635,7 +1732,7 @@ UpdateManager.prototype = {
|
||||
}
|
||||
else
|
||||
this._writeUpdatesToXMLFile([this._activeUpdate],
|
||||
getFile(KEY_APPDIR, [FILE_UPDATE_ACTIVE]));
|
||||
getUpdateFile([FILE_UPDATE_ACTIVE]));
|
||||
return activeUpdate;
|
||||
},
|
||||
|
||||
@@ -1707,10 +1804,10 @@ UpdateManager.prototype = {
|
||||
*/
|
||||
saveUpdates: function() {
|
||||
this._writeUpdatesToXMLFile([this._activeUpdate],
|
||||
getFile(KEY_APPDIR, [FILE_UPDATE_ACTIVE]));
|
||||
getUpdateFile([FILE_UPDATE_ACTIVE]));
|
||||
if (this._updates) {
|
||||
this._writeUpdatesToXMLFile(this._updates.slice(0, 10),
|
||||
getFile(KEY_APPDIR, [FILE_UPDATES_DB]));
|
||||
getUpdateFile([FILE_UPDATES_DB]));
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ USE_STATIC_LIBS = 1
|
||||
HAVE_PROGRESSUI = 1
|
||||
RCINCLUDE = updater.rc
|
||||
CPPSRCS += progressui_win.cpp
|
||||
OS_LIBS += $(call EXPAND_LIBNAME,comctl32 ws2_32)
|
||||
OS_LIBS += $(call EXPAND_LIBNAME,comctl32 ws2_32 shell32)
|
||||
ifndef GNU_CC
|
||||
RCFLAGS += -I$(srcdir)
|
||||
else
|
||||
|
||||
@@ -1022,7 +1022,7 @@ LaunchCallbackApp(const char *workingDir, int argc, char **argv)
|
||||
#elif defined(XP_MACOSX)
|
||||
LaunchChild(argc, argv);
|
||||
#elif defined(XP_WIN)
|
||||
WinLaunchChild(argv[0], argc, argv);
|
||||
WinLaunchChild(argv[0], argc, argv, -1);
|
||||
#else
|
||||
# warning "Need implementaton of LaunchCallbackApp"
|
||||
#endif
|
||||
@@ -1200,8 +1200,10 @@ ActionList::Prepare()
|
||||
// If the action list is empty then we should fail in order to signal that
|
||||
// something has gone wrong. Otherwise we report success when nothing is
|
||||
// actually done. See bug 327140.
|
||||
if (mCount == 0)
|
||||
if (mCount == 0) {
|
||||
LOG(("empty action list\n"));
|
||||
return UNEXPECTED_ERROR;
|
||||
}
|
||||
|
||||
Action *a = mFirst;
|
||||
while (a) {
|
||||
|
||||
@@ -96,6 +96,10 @@ XPIDLSRCS = \
|
||||
nsIXULRuntime.idl \
|
||||
$(NULL)
|
||||
|
||||
ifeq ($(OS_ARCH),WINNT)
|
||||
XPIDLSRCS += nsIWinAppHelper.idl
|
||||
endif
|
||||
|
||||
EXPORTS = \
|
||||
xrecore.h \
|
||||
nsXULAppAPI.h \
|
||||
|
||||
@@ -98,6 +98,9 @@
|
||||
#include "nsIWindowWatcher.h"
|
||||
#include "nsIXULAppInfo.h"
|
||||
#include "nsIXULRuntime.h"
|
||||
#ifdef XP_WIN
|
||||
#include "nsIWinAppHelper.h"
|
||||
#endif
|
||||
|
||||
#include "nsCRT.h"
|
||||
#include "nsCOMPtr.h"
|
||||
@@ -138,6 +141,8 @@
|
||||
|
||||
#ifdef XP_WIN
|
||||
#include <process.h>
|
||||
#include <shlobj.h>
|
||||
#include "nsThreadUtils.h"
|
||||
#endif
|
||||
|
||||
#ifdef XP_OS2
|
||||
@@ -407,6 +412,75 @@ CheckArg(const char* aArg, const char **aParam = nsnull)
|
||||
return ARG_NONE;
|
||||
}
|
||||
|
||||
#if defined(XP_WIN)
|
||||
/**
|
||||
* Check for a commandline flag from the windows shell and remove it from the
|
||||
* argv used when restarting. Flags MUST be in the form -arg.
|
||||
*
|
||||
* @param aArg the parameter to check. Must be lowercase.
|
||||
*/
|
||||
static ArgResult
|
||||
CheckArgShell(const char* aArg)
|
||||
{
|
||||
char **curarg = gRestartArgv + 1; // skip argv[0]
|
||||
|
||||
while (*curarg) {
|
||||
char *arg = curarg[0];
|
||||
|
||||
if (arg[0] == '-') {
|
||||
++arg;
|
||||
|
||||
if (strimatch(aArg, arg)) {
|
||||
do {
|
||||
*curarg = *(curarg + 1);
|
||||
++curarg;
|
||||
} while (*curarg);
|
||||
|
||||
--gRestartArgc;
|
||||
|
||||
return ARG_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
++curarg;
|
||||
}
|
||||
|
||||
return ARG_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Spins up Windows DDE when the app needs to restart or the profile manager
|
||||
* will be displayed during startup and the app has been launched by the Windows
|
||||
* shell to open an url. This prevents Windows from displaying an error message
|
||||
* due to the DDE message not being acknowledged.
|
||||
*/
|
||||
static void
|
||||
ProcessDDE(nsINativeAppSupport* aNative)
|
||||
{
|
||||
// When the app is launched by the windows shell the windows shell
|
||||
// expects the app to be available for DDE messages and if it isn't
|
||||
// windows displays an error dialog. To prevent the error the DDE server
|
||||
// is enabled and pending events are processed when the app needs to
|
||||
// restart after it was launched by the shell with the requestpending
|
||||
// argument. The requestpending pending argument is removed to
|
||||
// differentiate it from being launched when an app restart is not
|
||||
// required.
|
||||
ArgResult ar;
|
||||
ar = CheckArgShell("requestpending");
|
||||
if (ar == ARG_FOUND) {
|
||||
aNative->Enable(); // enable win32 DDE responses
|
||||
nsIThread *thread = NS_GetCurrentThread();
|
||||
// This is just a guesstimate based on testing different values.
|
||||
// If count is 8 or less windows will display an error dialog.
|
||||
PRInt32 count = 20;
|
||||
while(--count >= 0) {
|
||||
NS_ProcessNextEvent(thread);
|
||||
PR_Sleep(PR_MillisecondsToInterval(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
PRBool gSafeMode = PR_FALSE;
|
||||
|
||||
/**
|
||||
@@ -414,17 +488,29 @@ PRBool gSafeMode = PR_FALSE;
|
||||
* singleton.
|
||||
*/
|
||||
class nsXULAppInfo : public nsIXULAppInfo,
|
||||
#ifdef XP_WIN
|
||||
public nsIWinAppHelper,
|
||||
#endif
|
||||
public nsIXULRuntime
|
||||
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIXULAPPINFO
|
||||
NS_DECL_NSIXULRUNTIME
|
||||
#ifdef XP_WIN
|
||||
NS_DECL_NSIWINAPPHELPER
|
||||
private:
|
||||
nsresult LaunchAppHelperWithArgs(int aArgc, char **aArgv);
|
||||
#endif
|
||||
};
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsXULAppInfo)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXULRuntime)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIXULRuntime)
|
||||
#ifdef XP_WIN
|
||||
NS_INTERFACE_MAP_ENTRY(nsIWinAppHelper)
|
||||
#endif
|
||||
NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIXULAppInfo, gAppData)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
@@ -535,6 +621,92 @@ nsXULAppInfo::GetXPCOMABI(nsACString& aResult)
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef XP_WIN
|
||||
nsresult
|
||||
nsXULAppInfo::LaunchAppHelperWithArgs(int aArgc, char **aArgv)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIProperties> directoryService =
|
||||
do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsILocalFile> appHelper;
|
||||
rv = directoryService->Get(NS_XPCOM_CURRENT_PROCESS_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(appHelper));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = appHelper->AppendNative(NS_LITERAL_CSTRING("uninstall"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = appHelper->AppendNative(NS_LITERAL_CSTRING("helper.exe"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCAutoString appHelperPath;
|
||||
rv = appHelper->GetNativePath(appHelperPath);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!WinLaunchChild(appHelperPath.get(), aArgc, aArgv, 1))
|
||||
return NS_ERROR_FAILURE;
|
||||
else
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULAppInfo::FixReg()
|
||||
{
|
||||
int resetRegArgc = 2;
|
||||
char **resetRegArgv = (char**) malloc(sizeof(char*) * (resetRegArgc + 1));
|
||||
if (!resetRegArgv)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
resetRegArgv[0] = "argv0ignoredbywinlaunchchild";
|
||||
resetRegArgv[1] = "/fixreg";
|
||||
resetRegArgv[2] = nsnull;
|
||||
nsresult rv = LaunchAppHelperWithArgs(resetRegArgc, resetRegArgv);
|
||||
free(resetRegArgv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULAppInfo::PostUpdate(nsILocalFile *aLogFile)
|
||||
{
|
||||
nsresult rv;
|
||||
int upgradeArgc = aLogFile ? 3 : 2;
|
||||
char **upgradeArgv = (char**) malloc(sizeof(char*) * (upgradeArgc + 1));
|
||||
|
||||
if (!upgradeArgv)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
upgradeArgv[0] = "argv0ignoredbywinlaunchchild";
|
||||
upgradeArgv[1] = "/postupdate";
|
||||
|
||||
char *pathArg = nsnull;
|
||||
|
||||
if (aLogFile) {
|
||||
nsCAutoString logFilePath;
|
||||
rv = aLogFile->GetNativePath(logFilePath);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
pathArg = PR_smprintf("/uninstalllog=%s", logFilePath.get());
|
||||
if (!pathArg)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
upgradeArgv[2] = pathArg;
|
||||
upgradeArgv[3] = nsnull;
|
||||
}
|
||||
else {
|
||||
upgradeArgv[2] = nsnull;
|
||||
}
|
||||
|
||||
rv = LaunchAppHelperWithArgs(upgradeArgc, upgradeArgv);
|
||||
|
||||
if (pathArg)
|
||||
PR_smprintf_free(pathArg);
|
||||
|
||||
free(upgradeArgv);
|
||||
return rv;
|
||||
}
|
||||
#endif
|
||||
|
||||
static const nsXULAppInfo kAppInfo;
|
||||
static NS_METHOD AppInfoConstructor(nsISupports* aOuter,
|
||||
REFNSIID aIID, void **aResult)
|
||||
@@ -1199,6 +1371,27 @@ XRE_GetBinaryPath(const char* argv0, nsILocalFile* *aResult)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// copied from nsXREDirProvider.cpp
|
||||
#ifdef XP_WIN
|
||||
static nsresult
|
||||
GetShellFolderPath(int folder, char result[MAXPATHLEN])
|
||||
{
|
||||
LPITEMIDLIST pItemIDList = NULL;
|
||||
|
||||
nsresult rv;
|
||||
if (SUCCEEDED(SHGetSpecialFolderLocation(NULL, folder, &pItemIDList)) &&
|
||||
SUCCEEDED(SHGetPathFromIDList(pItemIDList, result))) {
|
||||
rv = NS_OK;
|
||||
} else {
|
||||
rv = NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
CoTaskMemFree(pItemIDList);
|
||||
|
||||
return rv;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define NS_ERROR_LAUNCHED_CHILD_PROCESS NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_PROFILE, 200)
|
||||
|
||||
#ifdef XP_WIN
|
||||
@@ -1237,7 +1430,7 @@ static nsresult LaunchChild(nsINativeAppSupport* aNative,
|
||||
return rv;
|
||||
|
||||
#if defined(XP_WIN)
|
||||
if (!WinLaunchChild(exePath.get(), gRestartArgc, gRestartArgv))
|
||||
if (!WinLaunchChild(exePath.get(), gRestartArgc, gRestartArgv, 0))
|
||||
return NS_ERROR_FAILURE;
|
||||
#elif defined(XP_OS2)
|
||||
if (_execv(exePath.get(), gRestartArgv) == -1)
|
||||
@@ -1369,6 +1562,10 @@ ShowProfileManager(nsIToolkitProfileService* aProfileSvc,
|
||||
SetupMacCommandLine(gRestartArgc, gRestartArgv);
|
||||
#endif
|
||||
|
||||
#ifdef XP_WIN
|
||||
ProcessDDE(aNative);
|
||||
#endif
|
||||
|
||||
{ //extra scoping is needed so we release these components before xpcom shutdown
|
||||
nsCOMPtr<nsIWindowWatcher> windowWatcher
|
||||
(do_GetService(NS_WINDOWWATCHER_CONTRACTID));
|
||||
@@ -2251,8 +2448,45 @@ XRE_main(int argc, char* argv[], const nsXREAppData* aAppData)
|
||||
|
||||
#if defined(MOZ_UPDATER)
|
||||
// Check for and process any available updates
|
||||
nsCOMPtr<nsIFile> updRoot = dirProvider.GetAppDir();
|
||||
nsCOMPtr<nsILocalFile> updRootl(do_QueryInterface(updRoot));
|
||||
|
||||
#ifdef XP_WIN
|
||||
// Use <UserLocalDataDir>\updates\<relative path to app dir from
|
||||
// Program Files> if app dir is under Program Files to avoid the
|
||||
// folder virtualization mess on Windows Vista
|
||||
char path[MAXPATHLEN];
|
||||
rv = GetShellFolderPath(CSIDL_PROGRAM_FILES, path);
|
||||
NS_ENSURE_SUCCESS(rv, 1);
|
||||
nsCOMPtr<nsILocalFile> programFilesDir;
|
||||
rv = NS_NewNativeLocalFile(nsDependentCString(path), PR_FALSE,
|
||||
getter_AddRefs(programFilesDir));
|
||||
NS_ENSURE_SUCCESS(rv, 1);
|
||||
|
||||
PRBool descendant;
|
||||
rv = programFilesDir->Contains(updRootl, PR_TRUE, &descendant);
|
||||
NS_ENSURE_SUCCESS(rv, 1);
|
||||
if (descendant) {
|
||||
nsCAutoString relativePath;
|
||||
rv = updRootl->GetRelativeDescriptor(programFilesDir, relativePath);
|
||||
NS_ENSURE_SUCCESS(rv, 1);
|
||||
|
||||
nsCOMPtr<nsILocalFile> userLocalDir;
|
||||
rv = dirProvider.GetUserLocalDataDirectory(getter_AddRefs(userLocalDir));
|
||||
NS_ENSURE_SUCCESS(rv, 1);
|
||||
|
||||
rv = NS_NewNativeLocalFile(EmptyCString(), PR_FALSE,
|
||||
getter_AddRefs(updRootl));
|
||||
NS_ENSURE_SUCCESS(rv, 1);
|
||||
|
||||
rv = updRootl->SetRelativeDescriptor(userLocalDir, relativePath);
|
||||
NS_ENSURE_SUCCESS(rv, 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
ProcessUpdates(dirProvider.GetGREDir(),
|
||||
dirProvider.GetAppDir(),
|
||||
updRootl,
|
||||
gRestartArgc,
|
||||
gRestartArgv);
|
||||
#endif
|
||||
@@ -2543,6 +2777,10 @@ XRE_main(int argc, char* argv[], const nsXREAppData* aAppData)
|
||||
// registry - major milestone vs. build id.
|
||||
needsRestart = PR_TRUE;
|
||||
|
||||
#ifdef XP_WIN
|
||||
ProcessDDE(nativeApp);
|
||||
#endif
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
SetupMacCommandLine(gRestartArgc, gRestartArgv);
|
||||
#endif
|
||||
|
||||
@@ -119,7 +119,7 @@ WriteConsoleLog();
|
||||
|
||||
#ifdef XP_WIN
|
||||
BOOL
|
||||
WinLaunchChild(const char *exePath, int argc, char **argv);
|
||||
WinLaunchChild(const char *exePath, int argc, char **argv, int needElevation);
|
||||
#endif
|
||||
|
||||
#define NS_NATIVEAPPSUPPORT_CONTRACTID "@mozilla.org/toolkit/native-app-support;1"
|
||||
|
||||
54
mozilla/toolkit/xre/nsIWinAppHelper.idl
Normal file
54
mozilla/toolkit/xre/nsIWinAppHelper.idl
Normal file
@@ -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 post update cleanup
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Seth Spitzer <sspitzer@mozilla.org>
|
||||
* Portions created by the Initial Developer are Copyright (C) 2007
|
||||
* 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 "nsISupports.idl"
|
||||
|
||||
/**
|
||||
* A scriptable interface used on Windows only to do some work from
|
||||
* a special process that gets created with elevated privileges.
|
||||
*
|
||||
* @status UNSTABLE - This interface is not frozen and will probably change in
|
||||
* future releases.
|
||||
*/
|
||||
|
||||
interface nsILocalFile;
|
||||
|
||||
[scriptable, uuid(575249a7-de7a-4602-a997-b7ad2b3b6dab)]
|
||||
interface nsIWinAppHelper : nsISupports
|
||||
{
|
||||
void postUpdate(in nsILocalFile logFile);
|
||||
void fixReg();
|
||||
};
|
||||
@@ -21,6 +21,7 @@
|
||||
*
|
||||
* Contributor(s):
|
||||
* Bill Law law@netscape.com
|
||||
* Robert Strong robert.bugzilla@gmail.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
|
||||
@@ -256,10 +257,10 @@ private:
|
||||
* whether Mozilla is already running.
|
||||
*/
|
||||
|
||||
/* Update 2006 September
|
||||
/* Update 2007 January
|
||||
*
|
||||
* A change in behavior was implemented in July 2004 which made the
|
||||
* application add on launch and remove on quit the ddexec registry key.
|
||||
* application on launch to add and on quit to remove the ddexec registry key.
|
||||
* See bug 246078.
|
||||
* Windows Vista has changed the methods used to set an application as default
|
||||
* and the new methods are incompatible with removing the ddeexec registry key.
|
||||
@@ -280,21 +281,20 @@ private:
|
||||
* for the verb (e.g. open).
|
||||
*
|
||||
* Application DDE Sequence:
|
||||
* 1. If the application is running a DDE request is received DDE with the
|
||||
* 1. If the application is running a DDE request is received with the
|
||||
* WWW_OpenURL topic and the params as specified in the default value of the
|
||||
* ddeexec registry key (e.g. "%1",,0,0,,,, where '%1' is the url to open)
|
||||
* for the verb (e.g. open).
|
||||
* 2. If the application is not running it is launched with the -url argument.
|
||||
* 2. If the application is not running it is launched with the -requestPending
|
||||
* and the -url argument.
|
||||
* 2.1 If the application does not need to restart and the -requestPending
|
||||
* argument is present the accompanying url will not be used. Instead the
|
||||
* application will wait for the DDE message to open the url.
|
||||
* 2.2 If the application needs to restart the -requestPending argument is
|
||||
* removed from the arguments used to restart the application and the url
|
||||
* will be handled normally.
|
||||
*
|
||||
* Note: Typically the application should use the DDE request to open the page
|
||||
* instead of using a command line argument. The command line argument is
|
||||
* used to work around when the DDE queue is hung by a different
|
||||
* application. See bug 53952.
|
||||
*
|
||||
* 3. The application receives a DDE request with the WWW_OpenURL topic and the
|
||||
* params from the ifexec key without the url (e.g. ,,0,0,,,,). The
|
||||
* application treats this request as a noop internally and returns the
|
||||
* correct values for the DDE request to the OS.
|
||||
* Note: Due to a bug in IE the ifexec key should not be used (see bug 355650).
|
||||
*/
|
||||
|
||||
class nsNativeAppSupportWin : public nsNativeAppSupportBase,
|
||||
@@ -457,6 +457,7 @@ NS_CreateNativeAppSupport( nsINativeAppSupport **aResult ) {
|
||||
|
||||
// Constants
|
||||
#define MOZ_DDE_APPLICATION "Mozilla"
|
||||
#define MOZ_MUTEX_NAMESPACE "Local\\"
|
||||
#define MOZ_STARTUP_MUTEX_NAME "StartupMutex"
|
||||
#define MOZ_DDE_START_TIMEOUT 30000
|
||||
#define MOZ_DDE_STOP_TIMEOUT 15000
|
||||
@@ -677,7 +678,8 @@ nsNativeAppSupportWin::Start( PRBool *aResult ) {
|
||||
// Grab mutex first.
|
||||
|
||||
// Build mutex name from app name.
|
||||
::_snprintf( mMutexName, sizeof mMutexName, "%s%s", gAppData->name, MOZ_STARTUP_MUTEX_NAME );
|
||||
::_snprintf( mMutexName, sizeof mMutexName, "%s%s%s", MOZ_MUTEX_NAMESPACE,
|
||||
gAppData->name, MOZ_STARTUP_MUTEX_NAME );
|
||||
Mutex startupLock = Mutex( mMutexName );
|
||||
|
||||
NS_ENSURE_TRUE( startupLock.Lock( MOZ_DDE_START_TIMEOUT ), NS_ERROR_FAILURE );
|
||||
@@ -835,6 +837,9 @@ nsNativeAppSupportWin::Quit() {
|
||||
}
|
||||
DdeUninitialize( mInstance );
|
||||
mInstance = 0;
|
||||
#if MOZ_DEBUG_DDE
|
||||
printf( "DDE server stopped\n" );
|
||||
#endif
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@@ -978,25 +983,23 @@ nsNativeAppSupportWin::HandleDDENotification( UINT uType, // transaction t
|
||||
nsCAutoString url;
|
||||
ParseDDEArg(hsz2, 0, url);
|
||||
|
||||
if ( !url.Equals( "" ) ) {
|
||||
// Read the 3rd argument in the command to determine if a
|
||||
// new window is to be used.
|
||||
nsCAutoString windowID;
|
||||
ParseDDEArg(hsz2, 2, windowID);
|
||||
// "" means to open the URL in a new window.
|
||||
if ( windowID.Equals( "" ) ) {
|
||||
url.Insert("mozilla -new-window ", 0);
|
||||
}
|
||||
else {
|
||||
url.Insert("mozilla -url ", 0);
|
||||
}
|
||||
// Read the 3rd argument in the command to determine if a
|
||||
// new window is to be used.
|
||||
nsCAutoString windowID;
|
||||
ParseDDEArg(hsz2, 2, windowID);
|
||||
// "" means to open the URL in a new window.
|
||||
if ( windowID.Equals( "" ) ) {
|
||||
url.Insert("mozilla -new-window ", 0);
|
||||
}
|
||||
else {
|
||||
url.Insert("mozilla -url ", 0);
|
||||
}
|
||||
|
||||
#if MOZ_DEBUG_DDE
|
||||
printf( "Handling dde XTYP_REQUEST request: [%s]...\n", url.get() );
|
||||
printf( "Handling dde XTYP_REQUEST request: [%s]...\n", url.get() );
|
||||
#endif
|
||||
// Now handle it.
|
||||
HandleCommandLine(url.get(), nsnull, nsICommandLine::STATE_REMOTE_EXPLICIT);
|
||||
}
|
||||
// Now handle it.
|
||||
HandleCommandLine(url.get(), nsnull, nsICommandLine::STATE_REMOTE_EXPLICIT);
|
||||
|
||||
// Return pseudo window ID.
|
||||
result = CreateDDEData( 1 );
|
||||
@@ -1151,25 +1154,23 @@ nsNativeAppSupportWin::HandleDDENotification( UINT uType, // transaction t
|
||||
nsCAutoString url;
|
||||
ParseDDEArg((const char*) request, 0, url);
|
||||
|
||||
if ( !url.Equals( "" ) ) {
|
||||
// Read the 3rd argument in the command to determine if a
|
||||
// new window is to be used.
|
||||
nsCAutoString windowID;
|
||||
ParseDDEArg((const char*) request, 2, windowID);
|
||||
// Read the 3rd argument in the command to determine if a
|
||||
// new window is to be used.
|
||||
nsCAutoString windowID;
|
||||
ParseDDEArg((const char*) request, 2, windowID);
|
||||
|
||||
// "" means to open the URL in a new window.
|
||||
if ( windowID.Equals( "" ) ) {
|
||||
url.Insert("mozilla -new-window ", 0);
|
||||
}
|
||||
else {
|
||||
url.Insert("mozilla -url ", 0);
|
||||
}
|
||||
#if MOZ_DEBUG_DDE
|
||||
printf( "Handling dde XTYP_REQUEST request: [%s]...\n", url.get() );
|
||||
#endif
|
||||
// Now handle it.
|
||||
HandleCommandLine(url.get(), nsnull, nsICommandLine::STATE_REMOTE_EXPLICIT);
|
||||
// "" means to open the URL in a new window.
|
||||
if ( windowID.Equals( "" ) ) {
|
||||
url.Insert("mozilla -new-window ", 0);
|
||||
}
|
||||
else {
|
||||
url.Insert("mozilla -url ", 0);
|
||||
}
|
||||
#if MOZ_DEBUG_DDE
|
||||
printf( "Handling dde XTYP_REQUEST request: [%s]...\n", url.get() );
|
||||
#endif
|
||||
// Now handle it.
|
||||
HandleCommandLine(url.get(), nsnull, nsICommandLine::STATE_REMOTE_EXPLICIT);
|
||||
|
||||
// Release the data.
|
||||
DdeUnaccessData( hdata );
|
||||
|
||||
@@ -435,7 +435,7 @@ ApplyUpdate(nsIFile *greDir, nsIFile *updateDir, nsILocalFile *statusFile,
|
||||
#elif defined(XP_WIN)
|
||||
_chdir(applyToDir.get());
|
||||
|
||||
if (!WinLaunchChild(updaterPath.get(), appArgc + 4, argv))
|
||||
if (!WinLaunchChild(updaterPath.get(), appArgc + 4, argv, 1))
|
||||
return;
|
||||
_exit(0);
|
||||
#else
|
||||
@@ -464,12 +464,13 @@ end:
|
||||
}
|
||||
|
||||
nsresult
|
||||
ProcessUpdates(nsIFile *greDir, nsIFile *appDir, int argc, char **argv)
|
||||
ProcessUpdates(nsIFile *greDir, nsIFile *appDir, nsIFile *updRootDir,
|
||||
int argc, char **argv)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsIFile> updatesDir;
|
||||
rv = appDir->Clone(getter_AddRefs(updatesDir));
|
||||
rv = updRootDir->Clone(getter_AddRefs(updatesDir));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
rv = updatesDir->AppendNative(NS_LITERAL_CSTRING("updates"));
|
||||
|
||||
@@ -58,6 +58,7 @@ class nsIFile;
|
||||
* This function does not modify appDir.
|
||||
*/
|
||||
NS_HIDDEN_(nsresult) ProcessUpdates(nsIFile *greDir, nsIFile *appDir,
|
||||
nsIFile *updRootDir,
|
||||
int argc, char **argv);
|
||||
|
||||
#endif // nsUpdateDriver_h__
|
||||
|
||||
@@ -44,6 +44,24 @@
|
||||
#define nsWindowsRestart_cpp
|
||||
#endif
|
||||
|
||||
#include <shellapi.h>
|
||||
|
||||
#ifndef ERROR_ELEVATION_REQUIRED
|
||||
#define ERROR_ELEVATION_REQUIRED 740L
|
||||
#endif
|
||||
|
||||
BOOL (WINAPI *pCreateProcessWithTokenW)(HANDLE,
|
||||
DWORD,
|
||||
LPCWSTR,
|
||||
LPWSTR,
|
||||
DWORD,
|
||||
LPVOID,
|
||||
LPCWSTR,
|
||||
LPSTARTUPINFOW,
|
||||
LPPROCESS_INFORMATION);
|
||||
|
||||
BOOL (WINAPI *pIsUserAnAdmin)(VOID);
|
||||
|
||||
/**
|
||||
* Get the length that the string will take when it is quoted.
|
||||
*/
|
||||
@@ -117,37 +135,159 @@ MakeCommandLine(int argc, char **argv)
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* alloc and convert multibyte char to unicode char
|
||||
*/
|
||||
static PRUnichar *
|
||||
AllocConvertAToW(const char *buf)
|
||||
{
|
||||
PRUint32 inputLen = strlen(buf) + 1;
|
||||
int n = MultiByteToWideChar(CP_ACP, 0, buf, inputLen, NULL, 0);
|
||||
if (n <= 0)
|
||||
return NULL;
|
||||
PRUnichar *result = (PRUnichar *)malloc(n * sizeof(PRUnichar));
|
||||
if (!result)
|
||||
return NULL;
|
||||
MultiByteToWideChar(CP_ACP, 0, buf, inputLen, result, n);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Launch a child process without elevated privilege.
|
||||
*/
|
||||
static BOOL
|
||||
LaunchAsNormalUser(const char *exePath, char *cl)
|
||||
{
|
||||
if (!pCreateProcessWithTokenW) {
|
||||
// IsUserAnAdmin is not present on Win9x and not exported by name on Win2k
|
||||
*(FARPROC *)&pIsUserAnAdmin =
|
||||
GetProcAddress(GetModuleHandle("shell32.dll"), "IsUserAnAdmin");
|
||||
|
||||
// CreateProcessWithTokenW is not present on WinXP or earlier
|
||||
*(FARPROC *)&pCreateProcessWithTokenW =
|
||||
GetProcAddress(GetModuleHandle("advapi32.dll"),
|
||||
"CreateProcessWithTokenW");
|
||||
|
||||
if (!pCreateProcessWithTokenW)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// do nothing here if we are not elevated or IsUserAnAdmin is not present.
|
||||
if (!pIsUserAnAdmin || pIsUserAnAdmin && !pIsUserAnAdmin())
|
||||
return FALSE;
|
||||
|
||||
// borrow the shell token to drop the privilege
|
||||
HWND hwndShell = FindWindow("Progman", NULL);
|
||||
DWORD dwProcessId;
|
||||
GetWindowThreadProcessId(hwndShell, &dwProcessId);
|
||||
|
||||
HANDLE hProcessShell = OpenProcess(MAXIMUM_ALLOWED, FALSE, dwProcessId);
|
||||
if (!hProcessShell)
|
||||
return FALSE;
|
||||
|
||||
HANDLE hTokenShell;
|
||||
BOOL ok = OpenProcessToken(hProcessShell, MAXIMUM_ALLOWED, &hTokenShell);
|
||||
CloseHandle(hProcessShell);
|
||||
if (!ok)
|
||||
return FALSE;
|
||||
|
||||
HANDLE hNewToken;
|
||||
ok = DuplicateTokenEx(hTokenShell,
|
||||
MAXIMUM_ALLOWED,
|
||||
NULL,
|
||||
SecurityDelegation,
|
||||
TokenPrimary,
|
||||
&hNewToken);
|
||||
CloseHandle(hTokenShell);
|
||||
if (!ok)
|
||||
return FALSE;
|
||||
|
||||
STARTUPINFOW si = {sizeof(si), 0};
|
||||
PROCESS_INFORMATION pi = {0};
|
||||
|
||||
PRUnichar *exePathW = AllocConvertAToW(exePath);
|
||||
PRUnichar *clW = AllocConvertAToW(cl);
|
||||
ok = exePathW && clW;
|
||||
if (ok) {
|
||||
ok = pCreateProcessWithTokenW(hNewToken,
|
||||
0, // profile is already loaded
|
||||
exePathW,
|
||||
clW,
|
||||
0, // No special process creation flags
|
||||
NULL, // inherit my environment
|
||||
NULL, // use my current directory
|
||||
&si,
|
||||
&pi);
|
||||
}
|
||||
free(exePathW);
|
||||
free(clW);
|
||||
CloseHandle(hNewToken);
|
||||
if (!ok)
|
||||
return FALSE;
|
||||
|
||||
CloseHandle(pi.hProcess);
|
||||
CloseHandle(pi.hThread);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Launch a child process with the specified arguments.
|
||||
* @param needElevation 1:need elevation, -1:want to drop priv, 0:don't care
|
||||
* @note argv[0] is ignored
|
||||
*/
|
||||
BOOL
|
||||
WinLaunchChild(const char *exePath, int argc, char **argv)
|
||||
WinLaunchChild(const char *exePath, int argc, char **argv, int needElevation)
|
||||
{
|
||||
char *cl = MakeCommandLine(argc, argv);
|
||||
char *cl;
|
||||
BOOL ok;
|
||||
if (needElevation > 0) {
|
||||
cl = MakeCommandLine(argc - 1, argv + 1);
|
||||
if (!cl)
|
||||
return FALSE;
|
||||
ok = ShellExecute(NULL, // no special UI window
|
||||
NULL, // use default verb
|
||||
exePath,
|
||||
cl,
|
||||
NULL, // use my current directory
|
||||
SW_SHOWDEFAULT) > (HINSTANCE)32;
|
||||
free(cl);
|
||||
return ok;
|
||||
}
|
||||
|
||||
cl = MakeCommandLine(argc, argv);
|
||||
if (!cl)
|
||||
return FALSE;
|
||||
|
||||
STARTUPINFO si = {sizeof(si), 0};
|
||||
PROCESS_INFORMATION pi = {0};
|
||||
if (needElevation < 0) {
|
||||
// try to launch as a normal user first
|
||||
ok = LaunchAsNormalUser(exePath, cl);
|
||||
// if it fails, fallback to normal launching
|
||||
if (!ok)
|
||||
needElevation = 0;
|
||||
}
|
||||
if (needElevation == 0) {
|
||||
STARTUPINFO si = {sizeof(si), 0};
|
||||
PROCESS_INFORMATION pi = {0};
|
||||
|
||||
BOOL ok = CreateProcess(exePath,
|
||||
cl,
|
||||
NULL, // no special security attributes
|
||||
NULL, // no special thread attributes
|
||||
FALSE, // don't inherit filehandles
|
||||
0, // No special process creation flags
|
||||
NULL, // inherit my environment
|
||||
NULL, // use my current directory
|
||||
&si,
|
||||
&pi);
|
||||
ok = CreateProcess(exePath,
|
||||
cl,
|
||||
NULL, // no special security attributes
|
||||
NULL, // no special thread attributes
|
||||
FALSE, // don't inherit filehandles
|
||||
0, // No special process creation flags
|
||||
NULL, // inherit my environment
|
||||
NULL, // use my current directory
|
||||
&si,
|
||||
&pi);
|
||||
|
||||
if (ok) {
|
||||
CloseHandle(pi.hProcess);
|
||||
CloseHandle(pi.hThread);
|
||||
}
|
||||
}
|
||||
|
||||
free(cl);
|
||||
|
||||
if (ok) {
|
||||
CloseHandle(pi.hProcess);
|
||||
CloseHandle(pi.hThread);
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user