Bug 1038560 - During uninstall use the precomplete file to determine files to uninstall instead of the uninstall.log. r=bbondy, a=lsblakk
authorRobert Strong <robert.bugzilla@gmail.com>
Tue, 18 Nov 2014 14:03:32 -0800
changeset 226252 af9b9ed74be4ce391172a4fff5b487d84d417397
parent 226251 62cd0230068f68bf948cc74398cfe6708ba26d71
child 226253 510ef39ea5ffec090e48be3d1be94ab01be3f367
push id7309
push userryanvm@gmail.com
push dateTue, 25 Nov 2014 20:37:06 +0000
treeherdermozilla-aurora@4af988d1770f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbbondy, lsblakk
bugs1038560
milestone35.0a2
Bug 1038560 - During uninstall use the precomplete file to determine files to uninstall instead of the uninstall.log. r=bbondy, a=lsblakk
browser/installer/windows/nsis/defines.nsi.in
browser/installer/windows/nsis/installer.nsi
browser/installer/windows/nsis/uninstaller.nsi
toolkit/mozapps/installer/windows/nsis/common.nsh
--- a/browser/installer/windows/nsis/defines.nsi.in
+++ b/browser/installer/windows/nsis/defines.nsi.in
@@ -31,18 +31,16 @@
 !define DDEApplication        "Firefox"
 !define AppRegName            "Firefox"
 
 !ifndef DEV_EDITION
 !define BrandShortName        "@MOZ_APP_DISPLAYNAME@"
 !endif
 !define BrandFullName         "${BrandFullNameInternal}"
 
-!define NO_UNINSTALL_SURVEY
-
 !define CERTIFICATE_NAME      "Mozilla Corporation"
 !define CERTIFICATE_ISSUER    "DigiCert Assured ID Code Signing CA-1"
 
 # LSP_CATEGORIES is the permitted LSP categories for the application. Each LSP
 # category value is ANDed together to set multiple permitted categories.
 # See http://msdn.microsoft.com/en-us/library/ms742253%28VS.85%29.aspx
 # The value below removes all LSP categories previously set.
 !define LSP_CATEGORIES "0x00000000"
--- a/browser/installer/windows/nsis/installer.nsi
+++ b/browser/installer/windows/nsis/installer.nsi
@@ -269,28 +269,16 @@ Section "-Application" APP_IDX
   ${RegisterDLL} "$INSTDIR\AccessibleMarshal.dll"
   ${If} ${Errors}
     ${LogMsg} "** ERROR Registering: $INSTDIR\AccessibleMarshal.dll **"
   ${Else}
     ${LogUninstall} "DLLReg: \AccessibleMarshal.dll"
     ${LogMsg} "Registered: $INSTDIR\AccessibleMarshal.dll"
   ${EndIf}
 
-  ; Write extra files created by the application to the uninstall log so they
-  ; will be removed when the application is uninstalled. To remove an empty
-  ; directory write a bogus filename to the deepest directory and all empty
-  ; parent directories will be removed.
-  ${LogUninstall} "File: \components\compreg.dat"
-  ${LogUninstall} "File: \components\xpti.dat"
-  ${LogUninstall} "File: \active-update.xml"
-  ${LogUninstall} "File: \install.log"
-  ${LogUninstall} "File: \install_status.log"
-  ${LogUninstall} "File: \install_wizard.log"
-  ${LogUninstall} "File: \updates.xml"
-
   ClearErrors
 
   ; Default for creating Start Menu shortcut
   ; (1 = create, 0 = don't create)
   ${If} $AddStartMenuSC == ""
     StrCpy $AddStartMenuSC "1"
   ${EndIf}
 
--- a/browser/installer/windows/nsis/uninstaller.nsi
+++ b/browser/installer/windows/nsis/uninstaller.nsi
@@ -88,37 +88,36 @@ VIAddVersionKey "OriginalFilename" "help
 !insertmacro RemoveDEHRegistrationIfMatching
 !endif
 !insertmacro SetAppLSPCategories
 !insertmacro SetBrandNameVars
 !insertmacro UpdateShortcutAppModelIDs
 !insertmacro UnloadUAC
 !insertmacro WriteRegDWORD2
 !insertmacro WriteRegStr2
-!insertmacro CheckIfRegistryKeyExists
 
 !insertmacro un.ChangeMUIHeaderImage
 !insertmacro un.CheckForFilesInUse
 !insertmacro un.CleanUpdateDirectories
 !insertmacro un.CleanVirtualStore
 !insertmacro un.DeleteShortcuts
 !insertmacro un.GetLongPath
 !insertmacro un.GetSecondInstallPath
 !insertmacro un.InitHashAppModelId
 !insertmacro un.ManualCloseAppPrompt
-!insertmacro un.ParseUninstallLog
 !insertmacro un.RegCleanAppHandler
 !insertmacro un.RegCleanFileHandler
 !insertmacro un.RegCleanMain
 !insertmacro un.RegCleanUninstall
 !insertmacro un.RegCleanProtocolHandler
 !ifdef MOZ_METRO
 !insertmacro un.RemoveDEHRegistrationIfMatching
 !endif
 !insertmacro un.RemoveQuotesFromPath
+!insertmacro un.RemovePrecompleteEntries
 !insertmacro un.SetAppLSPCategories
 !insertmacro un.SetBrandNameVars
 
 !include shared.nsh
 
 ; Helper macros for ui callbacks. Insert these after shared.nsh
 !insertmacro OnEndCommon
 !insertmacro UninstallOnInitCommon
@@ -157,38 +156,31 @@ ShowUnInstDetails nevershow
  * Uninstall Pages
  */
 ; Welcome Page
 !define MUI_PAGE_CUSTOMFUNCTION_PRE un.preWelcome
 !define MUI_PAGE_CUSTOMFUNCTION_LEAVE un.leaveWelcome
 !insertmacro MUI_UNPAGE_WELCOME
 
 ; Custom Uninstall Confirm Page
-UninstPage custom un.preConfirm un.leaveConfirm
+UninstPage custom un.preConfirm
 
 ; Remove Files Page
 !insertmacro MUI_UNPAGE_INSTFILES
 
 ; Finish Page
 
-; Don't setup the survey controls, functions, etc. when the application has
-; defined NO_UNINSTALL_SURVEY
-!ifndef NO_UNINSTALL_SURVEY
-!define MUI_PAGE_CUSTOMFUNCTION_PRE un.preFinish
-!define MUI_FINISHPAGE_SHOWREADME_NOTCHECKED
-!define MUI_FINISHPAGE_SHOWREADME ""
-!define MUI_FINISHPAGE_SHOWREADME_TEXT $(SURVEY_TEXT)
-!define MUI_FINISHPAGE_SHOWREADME_FUNCTION un.Survey
-!endif
-
 !insertmacro MUI_UNPAGE_FINISH
 
 ; Use the default dialog for IDD_VERIFY for a simple Banner
 ChangeUI IDD_VERIFY "${NSISDIR}\Contrib\UIs\default.exe"
 
+################################################################################
+# Helper Functions
+
 ; This function is used to uninstall the maintenance service if the
 ; application currently being uninstalled is the last application to use the 
 ; maintenance service.
 Function un.UninstallServiceIfNotUsed
   ; $0 will store if a subkey exists
   ; $1 will store the first subkey if it exists or an empty string if it doesn't
   ; Backup the old values
   Push $0
@@ -196,22 +188,24 @@ Function un.UninstallServiceIfNotUsed
 
   ; The maintenance service always uses the 64-bit registry on x64 systems
   ${If} ${RunningX64}
     SetRegView 64
   ${EndIf}
 
   ; Figure out the number of subkeys
   StrCpy $0 0
-loop:
-  EnumRegKey $1 HKLM "Software\Mozilla\MaintenanceService" $0
-  StrCmp $1 "" doneCount
-  IntOp $0 $0 + 1
-  goto loop
-doneCount:
+  ${Do}
+    EnumRegKey $1 HKLM "Software\Mozilla\MaintenanceService" $0
+    ${If} "$1" == ""
+      ${ExitDo}
+    ${EndIf}
+    IntOp $0 $0 + 1
+  ${Loop}
+
   ; Restore back the registry view
   ${If} ${RunningX64}
     SetRegView lastUsed
   ${EndIf}
   ${If} $0 == 0
     ; Get the path of the maintenance service uninstaller
     ReadRegStr $1 HKLM ${MaintUninstallKey} "UninstallString"
 
@@ -412,38 +406,67 @@ Section "Uninstall"
   ${If} ${FileExists} "$INSTDIR\removed-files"
     Delete /REBOOTOK "$INSTDIR\removed-files"
   ${EndIf}
 
   ; Remove files that may be left behind by the application in the
   ; VirtualStore directory.
   ${un.CleanVirtualStore}
 
-  ; Parse the uninstall log to unregister dll's and remove all installed
-  ; files / directories this install is responsible for.
-  ${un.ParseUninstallLog}
+  ; Only unregister the dll if the registration points to this installation
+  ReadRegStr $R1 HKCR "CLSID\{0D68D6D0-D93D-4D08-A30D-F00DD1F45B24}\InProcServer32" ""
+  ${If} "$INSTDIR\AccessibleMarshal.dll" == "$R1"
+    ${UnregisterDLL} "$INSTDIR\AccessibleMarshal.dll"
+  ${EndIf}
+
+  StrCpy $R2 "false"
+  StrCpy $R3 "false"
+  ${un.RemovePrecompleteEntries} "$R2" "$R3"
+
+  RmDir /r /REBOOTOK "$INSTDIR\${TO_BE_DELETED}"
 
-  ; Remove the uninstall directory that we control
-  RmDir /r /REBOOTOK "$INSTDIR\uninstall"
+  ${If} ${FileExists} "$INSTDIR\defaults\pref\channel-prefs.js"
+    Delete /REBOOTOK "$INSTDIR\defaults\pref\channel-prefs.js"
+  ${EndIf}
+  ${If} ${FileExists} "$INSTDIR\defaults\pref"
+    RmDir /REBOOTOK "$INSTDIR\defaults\pref"
+  ${EndIf}
+  ${If} ${FileExists} "$INSTDIR\defaults"
+    RmDir /REBOOTOK "$INSTDIR\defaults"
+  ${EndIf}
+  ${If} ${FileExists} "$INSTDIR\uninstall"
+    ; Remove the uninstall directory that we control
+    RmDir /r /REBOOTOK "$INSTDIR\uninstall"
+  ${EndIf}
+  ${If} ${FileExists} "$INSTDIR\install.log"
+    Delete /REBOOTOK "$INSTDIR\install.log"
+  ${EndIf}
+  ${If} ${FileExists} "$INSTDIR\update-settings.ini"
+    Delete /REBOOTOK "$INSTDIR\update-settings.ini"
+  ${EndIf}
 
-  ; Explictly remove empty webapprt dir in case it exists
-  ; See bug 757978
+  ; Explictly remove empty webapprt dir in case it exists (bug 757978).
   RmDir "$INSTDIR\webapprt\components"
   RmDir "$INSTDIR\webapprt"
 
-  RmDir /r /REBOOTOK "$INSTDIR\${TO_BE_DELETED}"
-
   ; Remove the installation directory if it is empty
-  ${RemoveDir} "$INSTDIR"
+  RmDir "$INSTDIR"
 
   ; If firefox.exe was successfully deleted yet we still need to restart to
   ; remove other files create a dummy firefox.exe.moz-delete to prevent the
   ; installer from allowing an install without restart when it is required
   ; to complete an uninstall.
+
+  ; Admin is required to delete files on reboot so only add the moz-delete if
+  ; the user is an admin. After calling UAC::IsAdmin $0 will equal 1 if the user
+  ; is an admin.
+  UAC::IsAdmin
+
   ${If} ${RebootFlag}
+  ${AndIf} "$0" == "1"
     ${Unless} ${FileExists} "$INSTDIR\${FileMainEXE}.moz-delete"
       FileOpen $0 "$INSTDIR\${FileMainEXE}.moz-delete" w
       FileWrite $0 "Will be deleted on restart"
       Delete /REBOOTOK "$INSTDIR\${FileMainEXE}.moz-delete"
       FileClose $0
     ${EndUnless}
   ${EndIf}
 
@@ -453,42 +476,31 @@ Section "Uninstall"
   System::Call "shell32::SHChangeNotify(i ${SHCNE_ASSOCCHANGED}, i 0, i 0, i 0)"
 
 !ifdef MOZ_MAINTENANCE_SERVICE
   ; Get the path the allowed cert is at and remove it
   ; Keep this block of code last since it modfies the reg view
   ServicesHelper::PathToUniqueRegistryPath "$INSTDIR"
   Pop $MaintCertKey
   ${If} $MaintCertKey != ""
-    ; We always use the 64bit registry for certs
+    ; Always use the 64bit registry for certs on 64bit systems.
     ${If} ${RunningX64}
       SetRegView 64
     ${EndIf}
     DeleteRegKey HKLM "$MaintCertKey"
     ${If} ${RunningX64}
       SetRegView lastused
     ${EndIf}
   ${EndIf}
   Call un.UninstallServiceIfNotUsed
 !endif
 
 SectionEnd
 
 ################################################################################
-# Helper Functions
-
-; Don't setup the survey controls, functions, etc. when the application has
-; defined NO_UNINSTALL_SURVEY
-!ifndef NO_UNINSTALL_SURVEY
-Function un.Survey
-  Exec "$\"$TmpVal$\" $\"${SurveyURL}$\""
-FunctionEnd
-!endif
-
-################################################################################
 # Language
 
 !insertmacro MOZ_MUI_LANGUAGE 'baseLocale'
 !verbose push
 !verbose 3
 !include "overrideLocale.nsh"
 !include "customLocale.nsh"
 !verbose pop
@@ -589,60 +601,16 @@ Function un.preConfirm
   !insertmacro MUI_INSTALLOPTIONS_INITDIALOG "unconfirm.ini"
   GetDlgItem $0 $HWNDPARENT 1
   System::Call "user32::SetFocus(i r0, i 0x0007, i,i)i"
   ${MUI_INSTALLOPTIONS_READ} $1 "unconfirm.ini" "Field 2" "HWND"
   SendMessage $1 ${WM_SETTEXT} 0 "STR:$INSTDIR"
   !insertmacro MUI_INSTALLOPTIONS_SHOW
 FunctionEnd
 
-Function un.leaveConfirm
-  ; Try to delete the app executable and if we can't delete it try to find the
-  ; app's message window and prompt the user to close the app. This allows
-  ; running an instance that is located in another directory. If for whatever
-  ; reason there is no message window we will just rename the app's files and
-  ; then remove them on restart if they are in use.
-  ClearErrors
-  ${DeleteFile} "$INSTDIR\${FileMainEXE}"
-  ${If} ${Errors}
-    ${un.ManualCloseAppPrompt} "${WindowClass}" "$(WARN_MANUALLY_CLOSE_APP_UNINSTALL)"
-  ${EndIf}
-FunctionEnd
-
-!ifndef NO_UNINSTALL_SURVEY
-Function un.preFinish
-  ; Do not modify the finish page if there is a reboot pending
-  ${Unless} ${RebootFlag}
-    ; Setup the survey controls, functions, etc.
-    StrCpy $TmpVal "SOFTWARE\Microsoft\IE Setup\Setup"
-    ClearErrors
-    ReadRegStr $0 HKLM $TmpVal "Path"
-    ${If} ${Errors}
-      !insertmacro MUI_INSTALLOPTIONS_WRITE "ioSpecial.ini" "settings" "NumFields" "3"
-    ${Else}
-      ExpandEnvStrings $0 "$0" ; this value will usually contain %programfiles%
-      ${If} $0 != "\"
-        StrCpy $0 "$0\"
-      ${EndIf}
-      StrCpy $0 "$0\iexplore.exe"
-      ClearErrors
-      GetFullPathName $TmpVal $0
-      ${If} ${Errors}
-        !insertmacro MUI_INSTALLOPTIONS_WRITE "ioSpecial.ini" "settings" "NumFields" "3"
-      ${Else}
-        ; When we add an optional action to the finish page the cancel button
-        ; is enabled. This disables it and leaves the finish button as the
-        ; only choice.
-        !insertmacro MUI_INSTALLOPTIONS_WRITE "ioSpecial.ini" "settings" "cancelenabled" "0"
-      ${EndIf}
-    ${EndIf}
-  ${EndUnless}
-FunctionEnd
-!endif
-
 ################################################################################
 # Initialization Functions
 
 Function .onInit
   ; Remove the current exe directory from the search order.
   ; This only effects LoadLibrary calls and not implicitly loaded DLLs.
   System::Call 'kernel32::SetDllDirectoryW(w "")'
 
--- a/toolkit/mozapps/installer/windows/nsis/common.nsh
+++ b/toolkit/mozapps/installer/windows/nsis/common.nsh
@@ -4419,21 +4419,21 @@
       StrCmp "$R9" "\MapiProxy_InUse.dll" end +1 ; Skip the MapiProxy_InUse.dll
       StrCmp "$R9" "\mozMapi32_InUse.dll" end +1 ; Skip the mozMapi32_InUse.dll
 
       StrCpy $R1 "$INSTDIR$R9" ; Copy the install dir path and suffix it with the string
       IfFileExists "$R1" +1 end
 
       ${Unless} "$R2" == "false"
         IntOp $R2 $R2 + 2
-      ${EndIf}
+      ${EndUnless}
       ${Unless} "$R3" == "false"
         SendMessage $R3 ${PBM_STEPIT} 0 0
         SendMessage $R3 ${PBM_STEPIT} 0 0
-      ${EndIf}
+      ${EndUnless}
 
       ClearErrors
       Delete "$R1"
       ${Unless} ${Errors}
         Goto end
       ${EndUnless}
 
       GetTempFileName $R0 "$INSTDIR\${TO_BE_DELETED}"
@@ -4460,16 +4460,172 @@
   Push "${_INSTALL_STEP_COUNTER}"
   !verbose ${_MOZFUNC_VERBOSE}
   Call OnStubInstallUninstall
   Pop ${_INSTALL_STEP_COUNTER}
   !verbose pop
 !macroend
 
 /**
+ * Parses the precomplete file to remove an installation's files.
+ *
+ * When modifying this macro be aware that LineFind uses all registers except
+ * $R0-$R3 so be cautious. Callers of this macro are not affected.
+ *
+ * @param   _PROGRESSBAR
+ *          The progress bar to update using PBM_STEPIT. Can also be "false" if
+ *          updating a progressbar isn't needed.
+ * @param   _INSTALL_STEP_COUNTER
+ *          The install step counter to increment. The variable specified in
+ *          this parameter is also updated. Can also be "false" if a counter
+ *          isn't needed.
+ *
+ * $R2 = _PROGRESSBAR
+ * $R3 = _INSTALL_STEP_COUNTER
+ */
+!macro RemovePrecompleteEntries
+
+  !ifndef ${_MOZFUNC_UN}RemovePrecompleteEntries
+    !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN}
+    !insertmacro ${_MOZFUNC_UN_TMP}GetParent
+    !insertmacro ${_MOZFUNC_UN_TMP}LineFind
+    !insertmacro ${_MOZFUNC_UN_TMP}TrimNewLines
+    !insertmacro ${_MOZFUNC_UN_TMP}WordReplace
+    !undef _MOZFUNC_UN
+    !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP}
+    !undef _MOZFUNC_UN_TMP
+
+    !verbose push
+    !verbose ${_MOZFUNC_VERBOSE}
+    !define ${_MOZFUNC_UN}RemovePrecompleteEntries "!insertmacro ${_MOZFUNC_UN}RemovePrecompleteEntriesCall"
+
+    Function ${_MOZFUNC_UN}RemovePrecompleteEntries
+      Exch $R3
+      Exch 1
+      Exch $R2
+      Push $R1
+      Push $R0
+      Push $TmpVal
+
+      ${If} ${FileExists} "$INSTDIR\precomplete"
+        ; Copy the uninstall log file to a temporary file
+        GetTempFileName $TmpVal
+        CopyFiles /SILENT /FILESONLY "$INSTDIR\precomplete" "$TmpVal"
+
+        CreateDirectory "$INSTDIR\${TO_BE_DELETED}"
+
+        ; Rename and then remove files
+        ${${_MOZFUNC_UN}LineFind} "$TmpVal" "/NUL" "1:-1" "${_MOZFUNC_UN}RemovePrecompleteEntriesCallback"
+
+        ; Delete the temporary precomplete file
+        Delete /REBOOTOK "$TmpVal"
+      ${EndIf}
+
+      ClearErrors
+
+      Pop $TmpVal
+      Pop $R0
+      Pop $R1
+      Exch $R2
+      Exch 1
+      Exch $R3
+    FunctionEnd
+
+    Function ${_MOZFUNC_UN}RemovePrecompleteEntriesCallback
+      ${${_MOZFUNC_UN}TrimNewLines} "$R9" $R9
+      ; Replace all occurrences of "/" with "\".
+      ${${_MOZFUNC_UN}WordReplace} "$R9" "/" "\" "+" $R9
+
+      ; Copy the first 7 chars
+      StrCpy $R1 "$R9" 7
+      ${If} "$R1" == "remove "
+        ; Copy the string starting after the 8th char
+        StrCpy $R9 "$R9" "" 8
+        ; Copy all but the last char to remove the double quote.
+        StrCpy $R9 "$R9" -1
+        ${If} ${FileExists} "$INSTDIR\$R9"
+          ${Unless} "$R3" == "false"
+            IntOp $R3 $R3 + 2
+          ${EndUnless}
+          ${Unless} "$R2" == "false"
+            SendMessage $R2 ${PBM_STEPIT} 0 0
+            SendMessage $R2 ${PBM_STEPIT} 0 0
+          ${EndUnless}
+
+          ClearErrors
+          Delete "$INSTDIR\$R9"
+          ${If} ${Errors}
+            GetTempFileName $R0 "$INSTDIR\${TO_BE_DELETED}"
+            Delete "$R0"
+            ClearErrors
+            Rename "$INSTDIR\$R9" "$R0"
+!ifdef __UNINSTALL__
+            ${If} ${Errors}
+              Delete /REBOOTOK "$INSTDIR\$R9"
+            ${EndIf}
+!endif
+          ${EndIf}
+        ${EndIf}
+      ${ElseIf} "$R1" == "rmdir $\""
+        ; Copy the string starting after the 7th char.
+        StrCpy $R9 "$R9" "" 7
+        ; Copy all but the last two chars to remove the slash and the double quote.
+        StrCpy $R9 "$R9" -2
+        ${If} ${FileExists} "$INSTDIR\$R9"
+          ; Ignore directory removal errors
+          RmDir "$INSTDIR\$R9"
+        ${EndIf}
+      ${EndIf}
+
+      ClearErrors
+
+      Push 0
+    FunctionEnd
+
+    !verbose pop
+  !endif
+!macroend
+
+!macro RemovePrecompleteEntriesCall _PROGRESSBAR _INSTALL_STEP_COUNTER
+  !verbose push
+  Push "${_PROGRESSBAR}"
+  Push "${_INSTALL_STEP_COUNTER}"
+  !verbose ${_MOZFUNC_VERBOSE}
+  Call RemovePrecompleteEntries
+  Pop ${_INSTALL_STEP_COUNTER}
+  !verbose pop
+!macroend
+
+!macro un.RemovePrecompleteEntriesCall _PROGRESSBAR _INSTALL_STEP_COUNTER
+  !verbose push
+  !verbose ${_MOZFUNC_VERBOSE}
+  Push "${_PROGRESSBAR}"
+  Push "${_INSTALL_STEP_COUNTER}"
+  Call un.RemovePrecompleteEntries
+  Pop ${_INSTALL_STEP_COUNTER}
+  Pop $0
+  !verbose pop
+!macroend
+
+!macro un.RemovePrecompleteEntries
+  !ifndef un.RemovePrecompleteEntries
+    !verbose push
+    !verbose ${_MOZFUNC_VERBOSE}
+    !undef _MOZFUNC_UN
+    !define _MOZFUNC_UN "un."
+
+    !insertmacro RemovePrecompleteEntries
+
+    !undef _MOZFUNC_UN
+    !define _MOZFUNC_UN
+    !verbose pop
+  !endif
+!macroend
+
+/**
  * Parses the uninstall.log to unregister dll's, remove files, and remove
  * empty directories for this installation.
  *
  * When modifying this macro be aware that LineFind uses all registers except
  * $R0-$R3 so be cautious. Callers of this macro are not affected.
  */
 !macro un.ParseUninstallLog
 
@@ -7712,18 +7868,18 @@
 
 /**
  * Gets the elapsed time in seconds between two values in milliseconds stored as
  * an int64. The caller will typically get the millisecond values using
  * GetTickCount with a long return value as follows.
  * System::Call "kernel32::GetTickCount()l .s"
  * Pop $varname
  *
- * _START_TICK_COUNT    
- * _FINISH_TICK_COUNT   
+ * _START_TICK_COUNT
+ * _FINISH_TICK_COUNT
  * _RES_ELAPSED_SECONDS return value - elapsed time between _START_TICK_COUNT
  *                      and _FINISH_TICK_COUNT in seconds.
  */
 !macro GetSecondsElapsedCall _START_TICK_COUNT _FINISH_TICK_COUNT _RES_ELAPSED_SECONDS
   Push "${_START_TICK_COUNT}"
   Push "${_FINISH_TICK_COUNT}"
   ${CallArtificialFunction} GetSecondsElapsed_
   Pop ${_RES_ELAPSED_SECONDS}