Bug 368587 - avoid the second UAC prompt for helper.exe on software update by launching it directly from the elevated updater.exe process. r=bsmedberg, a1.8.1.7=dveditz for release-drivers

git-svn-id: svn://10.0.0.236/branches/MOZILLA_1_8_BRANCH@235414 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
rob_strong%exchangecode.com
2007-09-08 23:31:17 +00:00
parent a612ee0182
commit b4bd3644a7
5 changed files with 301 additions and 78 deletions

View File

@@ -62,9 +62,13 @@ Var TmpVal
!include WordFunc.nsh
!include MUI.nsh
!insertmacro FileJoin
!insertmacro GetOptions
!insertmacro GetParameters
!insertmacro LineFind
!insertmacro StrFilter
!insertmacro TextCompare
!insertmacro TrimNewLines
!insertmacro WordFind
!insertmacro WordReplace
@@ -86,6 +90,7 @@ VIAddVersionKey "FileDescription" "${BrandShortName} Helper"
!insertmacro AddHandlerValues
!insertmacro RegCleanMain
!insertmacro RegCleanUninstall
!insertmacro UpdateUninstallLog
!insertmacro WriteRegStr2
!insertmacro WriteRegDWORD2
@@ -228,7 +233,7 @@ Section "Uninstall"
${If} ${FileExists} "$INSTDIR\uninstall\uninstall.log"
; Copy the uninstall log file to a temporary file
GetTempFileName $TmpVal
CopyFiles "$INSTDIR\uninstall\uninstall.log" "$TmpVal"
CopyFiles /SILENT /FILESONLY "$INSTDIR\uninstall\uninstall.log" "$TmpVal"
; Unregister DLL's
${un.LineFind} "$TmpVal" "/NUL" "1:-1" "un.UnRegDLLsCallback"
@@ -471,7 +476,7 @@ Function .onInit
${If} ${FileExists} "$R3"
Delete "$INSTDIR\uninstall\*wizard*"
Delete "$INSTDIR\uninstall\uninstall.log"
CopyFiles /SILENT "$R3" "$INSTDIR\uninstall\"
CopyFiles /SILENT /FILESONLY "$R3" "$INSTDIR\uninstall\"
Push $R3
${GetParentDir}
Pop $R4
@@ -479,6 +484,8 @@ Function .onInit
RmDir "$R4"
${EndIf}
${EndUnless}
${Else}
${UpdateUninstallLog}
${EndUnless}
StrCpy $R1 "true"
${EndUnless}

View File

@@ -292,7 +292,8 @@ endif
ifdef MOZ_UPDATER
libs:: $(addprefix $(LOCALE_SRCDIR)/,updater/updater.ini)
ifeq ($(OS_ARCH),WINNT)
iconv -f UTF-8 -t $(WIN_INSTALLER_CHARSET) $< > $(FINAL_TARGET)/updater.ini
cat $< $(srcdir)/../installer/windows/nsis/updater_append.ini | \
iconv -f UTF-8 -t $(WIN_INSTALLER_CHARSET) > $(FINAL_TARGET)/updater.ini
else
ifneq (,$(filter mac cocoa,$(MOZ_WIDGET_TOOLKIT)))
$(SYSINSTALL) $(IFLAGS1) $^ $(FINAL_TARGET)/updater.app/Contents/MacOS

View File

@@ -389,11 +389,11 @@ Exch $R9 ; exchange the new $R9 value with the top of the stack
!macroend
!macro GetParentDir
Exch $R0
Push $R1
Push $R2
Push $R3
StrLen $R3 $R0
Exch $R0
Push $R1
Push $R2
Push $R3
StrLen $R3 $R0
${DoWhile} 1 > 0
IntOp $R1 $R1 - 1
${If} $R1 <= -$R3
@@ -1081,6 +1081,9 @@ Exch $R9 ; exchange the new $R9 value with the top of the stack
/**
* Writes a registry string using SHCTX and the supplied params and logs the
* action to the install log and the uninstall log if _LOG_UNINSTALL equals 1.
*
* Define NO_LOG to prevent all logging when calling this from the uninstaller.
*
* @param _ROOT
* The registry key root as defined by NSIS (e.g. HKLM, HKCU, etc.).
* This will only be used for logging.
@@ -1186,6 +1189,9 @@ Exch $R9 ; exchange the new $R9 value with the top of the stack
/**
* Writes a registry dword using SHCTX and the supplied params and logs the
* action to the install log and the uninstall log if _LOG_UNINSTALL equals 1.
*
* Define NO_LOG to prevent all logging when calling this from the uninstaller.
*
* @param _ROOT
* The registry key root as defined by NSIS (e.g. HKLM, HKCU, etc.).
* This will only be used for logging.
@@ -1291,6 +1297,9 @@ Exch $R9 ; exchange the new $R9 value with the top of the stack
/**
* Writes a registry string to HKCR using the supplied params and logs the
* action to the install log and the uninstall log if _LOG_UNINSTALL equals 1.
*
* Define NO_LOG to prevent all logging when calling this from the uninstaller.
*
* @param _ROOT
* The registry key root as defined by NSIS (e.g. HKLM, HKCU, etc.).
* This will only be used for logging.
@@ -1409,6 +1418,9 @@ Exch $R9 ; exchange the new $R9 value with the top of the stack
* Creates a registry key. This will log the actions to the install and
* uninstall logs. Alternatively you can set a registry value to create the key
* and then delete the value.
*
* Define NO_LOG to prevent all logging when calling this from the uninstaller.
*
* @param _ROOT
* The registry key root as defined by NSIS (e.g. HKLM, HKCU, etc.).
* @param _KEY
@@ -1910,95 +1922,220 @@ Exch $R9 ; exchange the new $R9 value with the top of the stack
*/
!macro GetPathFromString
!ifndef ${_MOZFUNC_UN}GetPathFromString
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
!define ${_MOZFUNC_UN}GetPathFromString "!insertmacro ${_MOZFUNC_UN}GetPathFromStringCall"
!ifndef ${_MOZFUNC_UN}GetPathFromString
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
!define ${_MOZFUNC_UN}GetPathFromString "!insertmacro ${_MOZFUNC_UN}GetPathFromStringCall"
Function ${_MOZFUNC_UN}GetPathFromString
Exch $R8
Push $R7
Push $R6
ClearErrors
Function ${_MOZFUNC_UN}GetPathFromString
Exch $R8
Push $R7
Push $R6
ClearErrors
StrCpy $R9 $R8
StrCpy $R6 0 ; Set the counter to 0.
StrCpy $R9 $R8
StrCpy $R6 0 ; Set the counter to 0.
ClearErrors
; Handle quoted paths with arguments.
StrCpy $R7 $R9 1 ; Copy the first char.
StrCmp $R7 '"' +2 +1 ; Is it a "?
StrCmp $R7 "'" +1 +9 ; Is it a '?
StrCpy $R9 $R9 "" 1 ; Remove the first char.
IntOp $R6 $R6 + 1 ; Increment the counter.
StrCpy $R7 $R9 1 $R6 ; Starting from the counter copy the next char.
StrCmp $R7 "" end ; Are there no more chars?
StrCmp $R7 '"' +2 +1 ; Is it a " char?
StrCmp $R7 "'" +1 -4 ; Is it a ' char?
StrCpy $R9 $R9 $R6 ; Copy chars up to the counter.
GoTo end
ClearErrors
; Handle quoted paths with arguments.
StrCpy $R7 $R9 1 ; Copy the first char.
StrCmp $R7 '"' +2 +1 ; Is it a "?
StrCmp $R7 "'" +1 +9 ; Is it a '?
StrCpy $R9 $R9 "" 1 ; Remove the first char.
IntOp $R6 $R6 + 1 ; Increment the counter.
StrCpy $R7 $R9 1 $R6 ; Starting from the counter copy the next char.
StrCmp $R7 "" end ; Are there no more chars?
StrCmp $R7 '"' +2 +1 ; Is it a " char?
StrCmp $R7 "'" +1 -4 ; Is it a ' char?
StrCpy $R9 $R9 $R6 ; Copy chars up to the counter.
GoTo end
; Handle DefaultIcon paths. DefaultIcon paths are not quoted and end with
; a , and a number.
IntOp $R6 $R6 - 1 ; Decrement the counter.
StrCpy $R7 $R9 1 $R6 ; Copy one char from the end minus the counter.
StrCmp $R7 '' +4 ; Are there no more chars?
StrCmp $R7 ',' +1 -3 ; Is it a , char?
StrCpy $R9 $R9 $R6 ; Copy chars up to the end minus the counter.
GoTo end
; Handle DefaultIcon paths. DefaultIcon paths are not quoted and end with
; a , and a number.
IntOp $R6 $R6 - 1 ; Decrement the counter.
StrCpy $R7 $R9 1 $R6 ; Copy one char from the end minus the counter.
StrCmp $R7 '' +4 ; Are there no more chars?
StrCmp $R7 ',' +1 -3 ; Is it a , char?
StrCpy $R9 $R9 $R6 ; Copy chars up to the end minus the counter.
GoTo end
; Handle unquoted paths with arguments. An unquoted path with arguments
; must be an 8dot3 path.
StrCpy $R6 -1 ; Set the counter to -1 so it will start at 0.
IntOp $R6 $R6 + 1 ; Increment the counter.
StrCpy $R7 $R9 1 $R6 ; Starting from the counter copy the next char.
StrCmp $R7 "" end ; Are there no more chars?
StrCmp $R7 " " +1 -3 ; Is it a space char?
StrCpy $R9 $R9 $R6 ; Copy chars up to the counter.
; Handle unquoted paths with arguments. An unquoted path with arguments
; must be an 8dot3 path.
StrCpy $R6 -1 ; Set the counter to -1 so it will start at 0.
IntOp $R6 $R6 + 1 ; Increment the counter.
StrCpy $R7 $R9 1 $R6 ; Starting from the counter copy the next char.
StrCmp $R7 "" end ; Are there no more chars?
StrCmp $R7 " " +1 -3 ; Is it a space char?
StrCpy $R9 $R9 $R6 ; Copy chars up to the counter.
end:
end:
Pop $R6
Pop $R7
Exch $R8
Push $R9
FunctionEnd
Pop $R6
Pop $R7
Exch $R8
Push $R9
FunctionEnd
!verbose pop
!endif
!verbose pop
!endif
!macroend
!macro GetPathFromStringCall _STRING _RESULT
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
Push "${_STRING}"
Call GetPathFromString
Pop ${_RESULT}
!verbose pop
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
Push "${_STRING}"
Call GetPathFromString
Pop ${_RESULT}
!verbose pop
!macroend
!macro un.GetPathFromStringCall _STRING _RESULT
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
Push "${_STRING}"
Call un.GetPathFromString
Pop ${_RESULT}
!verbose pop
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
Push "${_STRING}"
Call un.GetPathFromString
Pop ${_RESULT}
!verbose pop
!macroend
!macro un.GetPathFromString
!ifndef un.GetPathFromString
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
!undef _MOZFUNC_UN
!define _MOZFUNC_UN "un."
!ifndef un.GetPathFromString
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
!undef _MOZFUNC_UN
!define _MOZFUNC_UN "un."
!insertmacro GetPathFromString
!insertmacro GetPathFromString
!undef _MOZFUNC_UN
!define _MOZFUNC_UN
!verbose pop
!endif
!undef _MOZFUNC_UN
!define _MOZFUNC_UN
!verbose pop
!endif
!macroend
/**
* Updates the uninstall.log with new files added by software update.
*
* Requires FileJoin, LineFind, TextCompare, and TrimNewLines.
*
* IMPORTANT! The LineFind docs claim that it uses all registers except $R0-$R3.
* Though it appears that this is not true all registers besides
* $R0-$R3 may be overwritten so protect yourself!
*/
!macro UpdateUninstallLog
!ifndef ${_MOZFUNC_UN}UpdateUninstallLog
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
!define ${_MOZFUNC_UN}UpdateUninstallLog "!insertmacro ${_MOZFUNC_UN}UpdateUninstallLogCall"
Function ${_MOZFUNC_UN}UpdateUninstallLog
Push $R3
Push $R2
Push $R1
Push $R0
ClearErrors
GetFullPathName $R3 "$INSTDIR\uninstall"
IfFileExists "$R3\uninstall.update" +2 0
Return
${${_MOZFUNC_UN}LineFind} "$R3\uninstall.update" "" "1:-1" "${_MOZFUNC_UN}CleanupUpdateLog"
GetTempFileName $R2 "$R3"
FileOpen $R1 $R2 w
${${_MOZFUNC_UN}TextCompare} "$R3\uninstall.update" "$R3\uninstall.log" "SlowDiff" "${_MOZFUNC_UN}CreateUpdateDiff"
FileClose $R1
IfErrors +2 0
${${_MOZFUNC_UN}FileJoin} "$R3\uninstall.log" "$R2" "$R3\uninstall.log"
${DeleteFile} "$R2"
ClearErrors
Pop $R0
Pop $R1
Pop $R2
Pop $R3
FunctionEnd
; This callback MUST use labels vs. relative line numbers.
Function ${_MOZFUNC_UN}CleanupUpdateLog
StrCpy $R2 "$R9" 12
StrCmp "$R2" "EXECUTE ADD " 0 skip
StrCpy $R9 "$R9" "" 12
Push $R6
Push $R5
Push $R4
StrCpy $R4 "" ; Initialize to an empty string.
StrCpy $R6 -1 ; Set the counter to -1 so it will start at 0.
loop:
IntOp $R6 $R6 + 1 ; Increment the counter.
StrCpy $R5 $R9 1 $R6 ; Starting from the counter copy the next char.
StrCmp $R5 "" copy ; Are there no more chars?
StrCmp $R5 "/" 0 +2 ; Is the char a /?
StrCpy $R5 "\" ; Replace the char with a \.
StrCpy $R4 "$R4$R5"
GoTo loop
copy:
StrCpy $R9 "File: \$R4"
Pop $R6
Pop $R5
Pop $R4
GoTo end
skip:
StrCpy $0 "SkipWrite"
end:
Push $0
FunctionEnd
Function ${_MOZFUNC_UN}CreateUpdateDiff
${${_MOZFUNC_UN}TrimNewLines} "$9" "$9"
StrCmp $9 "" +2 0
FileWrite $R1 "$9$\r$\n"
Push 0
FunctionEnd
!verbose pop
!endif
!macroend
!macro UpdateUninstallLogCall
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
Call UpdateUninstallLog
!verbose pop
!macroend
!macro un.UpdateUninstallLogCall
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
Call un.UpdateUninstallLog
!verbose pop
!macroend
!macro un.UpdateUninstallLog
!ifndef un.UpdateUninstallLog
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
!undef _MOZFUNC_UN
!define _MOZFUNC_UN "un."
!insertmacro UpdateUninstallLog
!undef _MOZFUNC_UN
!define _MOZFUNC_UN
!verbose pop
!endif
!macroend
/**

View File

@@ -594,6 +594,16 @@ nsPostUpdateWin.prototype = {
},
run: function() {
// When uninstall/uninstall.update exists the uninstaller has already
// updated the uninstall.log with the files added by software update.
var updateUninstallFile = getFile(KEY_APPDIR);
updateUninstallFile.append("uninstall");
updateUninstallFile.append("uninstall.update");
if (updateUninstallFile.exists()) {
LOG("nothing to do, uninstall.log has already been updated");
return;
}
try {
installLogWriter = new InstallLogWriter();
try {

View File

@@ -263,6 +263,9 @@ private:
static char* gSourcePath;
static ArchiveReader gArchiveReader;
#ifdef XP_WIN
static bool gSucceeded = FALSE;
#endif
static const char kWhitespace[] = " \t";
static const char kNL[] = "\r\n";
@@ -1006,6 +1009,61 @@ PatchIfFile::Finish(int status)
#ifdef XP_WIN
#include "nsWindowsRestart.cpp"
static void
LaunchWinPostProcess(const char *appExe)
{
// Launch helper.exe to perform post processing (e.g. registry and log file
// modifications) for the update.
char inifile[MAXPATHLEN];
strcpy(inifile, appExe);
char *slash = strrchr(inifile, '\\');
if (!slash)
return;
strcpy(slash + 1, "updater.ini");
char exefile[MAXPATHLEN];
char exearg[MAXPATHLEN];
if (!GetPrivateProfileString("PostUpdateWin", "ExeRelPath", NULL, exefile,
sizeof(exefile), inifile))
return;
if (!GetPrivateProfileString("PostUpdateWin", "ExeArg", NULL, exearg,
sizeof(exearg), inifile))
return;
char exefullpath[MAXPATHLEN];
strcpy(exefullpath, appExe);
slash = strrchr(exefullpath, '\\');
strcpy(slash + 1, exefile);
char dlogFile[MAXPATHLEN];
strcpy(dlogFile, exefullpath);
slash = strrchr(dlogFile, '\\');
strcpy(slash + 1, "uninstall.update");
char slogFile[MAXPATHLEN];
snprintf(slogFile, MAXPATHLEN, "%s/update.log", gSourcePath);
// We want to launch the post update helper app to update the Windows
// registry even if there is a failure with removing the uninstall.update
// file or copying the update.log file.
ensure_remove(dlogFile);
copy_file(slogFile, dlogFile);
static int argc = 2;
static char **argv = (char**) malloc(sizeof(char*) * (argc + 1));
argv[0] = "argv0ignoredbywinlaunchchild";
argv[1] = exearg;
argv[2] = "\0";
WinLaunchChild(exefullpath, argc, argv, 1);
free(argv);
}
#endif
static void
@@ -1128,6 +1186,11 @@ int main(int argc, char **argv)
LogFinish();
#ifdef XP_WIN
if (gSucceeded)
LaunchWinPostProcess(argv[4]);
#endif
// The callback to execute is given as the last N arguments of our command
// line. The first of those arguments specifies the working directory for
// the callback.
@@ -1233,6 +1296,11 @@ ActionList::Finish(int status)
a = a->mNext;
}
#ifdef XP_WIN
if (status == OK)
gSucceeded = TRUE;
#endif
UpdateProgressUI(100.0f);
}