tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

postupdate_helper.nsh (5731B)


      1 # This Source Code Form is subject to the terms of the Mozilla Public
      2 # License, v. 2.0. If a copy of the MPL was not distributed with this
      3 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
      4 
      5 !include "LogicLib.nsh"
      6 
      7 !define buildNumWin10 10240 ; First Win10 version
      8 
      9 ; Depending on the installation type (as admin or not) we have different
     10 ; default installation directories, one of which we push onto the stack as the
     11 ; return value.
     12 Function getDefaultInstallDir
     13    Push $1 ; save $1 to restore it later
     14    UserInfo::GetAccountType
     15    Pop $1
     16    ${If} $1 == "User"
     17        ${GetLocalAppDataFolder} $1
     18        StrCpy $1 "$1\${BrandFullName}\"
     19        Push $1
     20    ${Else}
     21        !ifdef HAVE_64BIT_BUILD
     22            Push "$PROGRAMFILES64\${BrandFullName}\"
     23        !else
     24            Push "$PROGRAMFILES32\${BrandFullName}\"
     25        !endif
     26    ${EndIf}
     27    Exch
     28    Pop $1 ; restore $1
     29 FunctionEnd
     30 
     31 ; This function expects the topmost element of the stack to be the path to be
     32 ; normalized. It returns one of:
     33 ;   a) the resolved path with a maximum length of 1000 chars.
     34 ;   b) the string '[!] GetFullPathNameW: Insufficient buffer memory.' (error case)
     35 ;   c) the string '[!] GetFullPathNameW: Unknown error.' (should never happen)
     36 ;
     37 ; In all error cases (b, c) this function uses SetError to enable checks like:
     38 ;   ${If} ${Errors}
     39 ;   Pop $ErrorMessage
     40 ;   ${EndIf}
     41 ; This means that after calling this function it always returns a string value
     42 ; on the stack.
     43 Function getNormalizedPath
     44  Exch $0 ; Equivalent to: Push $0, Exch, Pop $0
     45  Push $1
     46  Push $2
     47 
     48  ; MAX_PATH defines a 260-character limit, but GetFullPathNameW can handle
     49  ; paths up to 32767 characters when using the "\\?\" prefix. Since NSIS
     50  ; registers are limited to 1024 bytes, we allow path length up to 1000 chars
     51  ; and leave 23 headroom for testing purposes.
     52  System::Call 'kernel32::GetFullPathNameW(w r0, i 1000, w .r1, i0) i .r2'
     53  # Check if return value in $0 is 0 (error)
     54  ${If} $2 == 0
     55    StrCpy $0 "[!] GetFullPathNameW: Unknown error."
     56    SetErrors
     57  ${OrIf} $2 >= 1000
     58    StrCpy $0 "[!] GetFullPathNameW: Insufficient buffer memory."
     59    SetErrors
     60  ${Else}
     61    StrCpy $0 $1
     62  ${EndIf}
     63 
     64  ; Restore the variables from the stack.
     65  Pop $2
     66  Pop $1
     67 
     68  ; Return the result on the stack and restore $0
     69  Exch $0
     70 FunctionEnd
     71 
     72 ; This function takes no arguments and returns the name of the legacy uninstall
     73 ; key stored on the stack.
     74 Function getLegacyUninstallKey
     75  Push $0
     76 
     77  ; $0 is used as the return value for this function. It is initially set to
     78  ; the Uninstall key, which has been standard for decades.
     79  StrCpy $0 "Software\Microsoft\Windows\CurrentVersion\Uninstall\${BrandFullNameInternal} ${AppVersion}"
     80  ${WordFind} "${UpdateChannel}" "esr" "E#" $1
     81  ${IfNot} ${Errors}
     82    StrCpy $0 "$0 ESR"
     83  ${EndIf}
     84  StrCpy $0 "$0 (${ARCH} ${AB_CD})"
     85 
     86  Exch $0
     87 FunctionEnd
     88 
     89 ; This function returns the uninstallation key used for installing applications
     90 ; in their default directory on the stack.
     91 Function getModernUninstallKey
     92  Push "Software\Microsoft\Windows\CurrentVersion\Uninstall\${BrandFullNameInternal}"
     93 FunctionEnd
     94 
     95 ; This function checks for a registry key under HKEY_LOCAL_MACHINE with a
     96 ; matching installation directory to $INSTDIR or an empty string if no matching
     97 ; installation is found.
     98 Function findUninstallKey
     99  Push $0
    100  Push $1
    101  Push $2
    102 
    103  ${GetLongPath} "$INSTDIR" $2
    104 
    105  Call getLegacyUninstallKey
    106  Pop $0
    107  ReadRegStr $1 "HKLM" $0 "InstallLocation"
    108  ${If} $1 != $2
    109    Call getModernUninstallKey
    110    Pop $0
    111    ReadRegStr $1 "HKLM" $0 "InstallLocation"
    112    ${If} $1 != $2
    113      StrCpy $0 ""
    114    ${EndIf}
    115  ${EndIf}
    116 
    117  Pop $2
    118  Pop $1
    119  Exch $0
    120 FunctionEnd
    121 
    122 ; This function expects the Windows build number as a parameter from the stack.
    123 ; It Returns the appropriate uninstall registry key on the stack.
    124 Function getUninstallKey
    125  Exch $3 ; Equivalent to: Push $3, Exch, Pop $3
    126  Push $0
    127  Push $1
    128  Push $2
    129 
    130  Call getLegacyUninstallKey
    131  Pop $0
    132 
    133  ${If} $3 >= ${buildNumWin10}
    134    ClearErrors
    135 
    136    ; Determine the path to the user configured target directory.
    137    Push "$INSTDIR\"
    138    Call getNormalizedPath
    139    Pop $2 ; contains the absolute path to the $INSTDIR (user definable) now.
    140 
    141    ; Determine the absolute path of the default installation directory
    142    Call getDefaultInstallDir ; pushes the default directory on the stack
    143    Call getNormalizedPath
    144    Pop $1 ; contains the absolute path to the default directory now.
    145 
    146    ${IfNot} ${Errors}
    147    ${AndIf} "$1" == "$2"
    148      ; The default path and target path matched.
    149      Call getModernUninstallKey
    150      Pop $0
    151      DetailPrint "Default installation detected."
    152    ${EndIf}
    153  ${EndIf}
    154 
    155  StrCpy $3 $0
    156  Pop $2
    157  Pop $1
    158  Pop $0
    159  ; Return the result on the stack and restore $0
    160  Exch $3
    161 FunctionEnd
    162 
    163 ; Looks at installation_telemetry.json to determine whether the installation
    164 ; was installed by the stub installer or not.
    165 ;
    166 ; Expects the JSON file on the stack as a parameter; will return the
    167 ; installation type from the JSON file, generally either "stub" or "full".
    168 ; On failure, pushes "unknown".
    169 Function GetInstallationType
    170  Exch $1 ; directory
    171  Push $0 ; temporary variable
    172 
    173  nsJSON::Set /file /unicode "$1"
    174  nsJSON::Get /type `installer_type` /end
    175 
    176  Pop $0
    177  ${If} $0 == ""
    178    ; It's only ever written as UTF-16, but decode it as ANSI for redundancy.
    179    nsJSON::Set /file "$1"
    180    nsJSON::Get /type `installer_type` /end
    181    Pop $0 ; type
    182  ${EndIf}
    183 
    184  ClearErrors
    185  StrCpy $1 "unknown"
    186  ${If} $0 == "string"
    187    nsJSON::Get `installer_type` /end
    188    ${IfNot} ${Errors}
    189      ; get the actual installer type from the file
    190      Pop $1
    191    ${EndIf}
    192  ${EndIf}
    193 
    194  Exch
    195  Pop $0
    196  Exch $1
    197  ClearErrors
    198 FunctionEnd