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# Required Plugins: 6# AppAssocReg 7# CertCheck 8# InetBgDL 9# ShellLink 10# UAC 11 12; Set verbosity to 3 (e.g. no script) to lessen the noise in the build logs 13!verbose 3 14 15SetDatablockOptimize on 16SetCompress off 17CRCCheck on 18 19RequestExecutionLevel user 20 21Unicode true 22ManifestSupportedOS all 23ManifestDPIAware true 24 25!addplugindir ./ 26 27Var CheckboxSetAsDefault 28Var CheckboxShortcuts 29Var CheckboxSendPing 30Var CheckboxInstallMaintSvc 31Var CheckboxCleanupProfile 32 33Var FontFamilyName 34 35Var CanWriteToInstallDir 36Var HasRequiredSpaceAvailable 37Var IsDownloadFinished 38Var DownloadSizeBytes 39Var DownloadReset 40Var ExistingTopDir 41Var SpaceAvailableBytes 42Var InitialInstallDir 43Var HandleDownload 44Var CanSetAsDefault 45Var InstallCounterStep 46Var InstallTotalSteps 47Var ProgressCompleted 48Var UsingHighContrastMode 49 50Var ExitCode 51Var FirefoxLaunchCode 52 53Var StartDownloadPhaseTickCount 54; Since the Intro and Options pages can be displayed multiple times the total 55; seconds spent on each of these pages is reported. 56Var IntroPhaseSeconds 57Var OptionsPhaseSeconds 58; The tick count for the last download. 59Var StartLastDownloadTickCount 60; The number of seconds from the start of the download phase until the first 61; bytes are received. This is only recorded for first request so it is possible 62; to determine connection issues for the first request. 63Var DownloadFirstTransferSeconds 64; The last four tick counts are for the end of a phase in the installation page. 65Var EndDownloadPhaseTickCount 66Var EndPreInstallPhaseTickCount 67Var EndInstallPhaseTickCount 68Var EndFinishPhaseTickCount 69 70Var InitialInstallRequirementsCode 71Var ExistingProfile 72Var ExistingVersion 73Var ExistingBuildID 74Var DownloadedBytes 75Var DownloadRetryCount 76Var OpenedDownloadPage 77Var DownloadServerIP 78Var PostSigningData 79Var PreviousInstallDir 80Var ProfileCleanupPromptType 81Var AppLaunchWaitTickCount 82Var TimerHandle 83 84!define ARCH_X86 1 85!define ARCH_AMD64 2 86!define ARCH_AARCH64 3 87Var ArchToInstall 88 89; Uncomment the following to prevent pinging the metrics server when testing 90; the stub installer 91;!define STUB_DEBUG 92 93!define StubURLVersion "v8" 94 95; Successful install exit code 96!define ERR_SUCCESS 0 97 98/** 99 * The following errors prefixed with ERR_DOWNLOAD apply to the download phase. 100 */ 101; The download was cancelled by the user 102!define ERR_DOWNLOAD_CANCEL 10 103 104; Too many attempts to download. The maximum attempts is defined in 105; DownloadMaxRetries. 106!define ERR_DOWNLOAD_TOO_MANY_RETRIES 11 107 108/** 109 * The following errors prefixed with ERR_PREINSTALL apply to the pre-install 110 * check phase. 111 */ 112; Unable to acquire a file handle to the downloaded file 113!define ERR_PREINSTALL_INVALID_HANDLE 20 114 115; The downloaded file's certificate is not trusted by the certificate store. 116!define ERR_PREINSTALL_CERT_UNTRUSTED 21 117 118; The downloaded file's certificate attribute values were incorrect. 119!define ERR_PREINSTALL_CERT_ATTRIBUTES 22 120 121; The downloaded file's certificate is not trusted by the certificate store and 122; certificate attribute values were incorrect. 123!define ERR_PREINSTALL_CERT_UNTRUSTED_AND_ATTRIBUTES 23 124 125; Timed out while waiting for the certificate checks to run. 126!define ERR_PREINSTALL_CERT_TIMEOUT 24 127 128/** 129 * The following errors prefixed with ERR_INSTALL apply to the install phase. 130 */ 131; The installation timed out. The installation timeout is defined by the number 132; of progress steps defined in InstallTotalSteps and the install timer 133; interval defined in InstallIntervalMS 134!define ERR_INSTALL_TIMEOUT 30 135 136; Maximum times to retry the download before displaying an error 137!define DownloadMaxRetries 9 138 139; Interval before retrying to download. 3 seconds is used along with 10 140; attempted downloads (the first attempt along with 9 retries) to give a 141; minimum of 30 seconds or retrying before giving up. 142!define DownloadRetryIntervalMS 3000 143 144; Interval for the download timer 145!define DownloadIntervalMS 200 146 147; Timeout for the certificate check 148!define PreinstallCertCheckMaxWaitSec 30 149 150; Interval for the install timer 151!define InstallIntervalMS 100 152 153; Number of steps for the install progress. 154; This might not be enough when installing on a slow network drive so it will 155; fallback to downloading the full installer if it reaches this number. 156 157; Approximately 150 seconds with a 100 millisecond timer. 158!define InstallCleanTotalSteps 1500 159 160; Approximately 165 seconds with a 100 millisecond timer. 161!define InstallPaveOverTotalSteps 1650 162 163; Blurb duty cycle 164!define BlurbDisplayMS 19500 165!define BlurbBlankMS 500 166 167; Interval between checks for the application window and progress bar updates. 168!define AppLaunchWaitIntervalMS 100 169 170; Total time to wait for the application to start before just exiting. 171!define AppLaunchWaitTimeoutMS 10000 172 173; Maximum value of the download/install/launch progress bar, and the end values 174; for each individual stage. 175!define PROGRESS_BAR_TOTAL_STEPS 500 176!define PROGRESS_BAR_DOWNLOAD_END_STEP 300 177!define PROGRESS_BAR_INSTALL_END_STEP 475 178!define PROGRESS_BAR_APP_LAUNCH_END_STEP 500 179 180; Amount of physical memory required for the 64-bit build to be selected (2 GB). 181; Machines with this or less RAM get the 32-bit build, even with a 64-bit OS. 182!define RAM_NEEDED_FOR_64BIT 0x80000000 183 184; Attempt to elevate Standard Users in addition to users that 185; are a member of the Administrators group. 186!define NONADMIN_ELEVATE 187 188!define CONFIG_INI "config.ini" 189!define PARTNER_INI "$EXEDIR\partner.ini" 190 191!ifndef FILE_SHARE_READ 192 !define FILE_SHARE_READ 1 193!endif 194!ifndef GENERIC_READ 195 !define GENERIC_READ 0x80000000 196!endif 197!ifndef OPEN_EXISTING 198 !define OPEN_EXISTING 3 199!endif 200!ifndef INVALID_HANDLE_VALUE 201 !define INVALID_HANDLE_VALUE -1 202!endif 203 204!define DefaultInstDir32bit "$PROGRAMFILES32\${BrandFullName}" 205!define DefaultInstDir64bit "$PROGRAMFILES64\${BrandFullName}" 206 207!include "LogicLib.nsh" 208!include "FileFunc.nsh" 209!include "TextFunc.nsh" 210!include "WinVer.nsh" 211!include "WordFunc.nsh" 212 213!insertmacro GetParameters 214!insertmacro GetOptions 215!insertmacro LineFind 216!insertmacro StrFilter 217 218!include "locales.nsi" 219!include "branding.nsi" 220 221!include "defines.nsi" 222 223; Must be included after defines.nsi 224!include "locale-fonts.nsh" 225 226; The OFFICIAL define is a workaround to support different urls for Release and 227; Beta since they share the same branding when building with other branches that 228; set the update channel to beta. 229!ifdef OFFICIAL 230!ifdef BETA_UPDATE_CHANNEL 231!undef URLStubDownloadX86 232!undef URLStubDownloadAMD64 233!undef URLStubDownloadAArch64 234!define URLStubDownloadX86 "https://download.mozilla.org/?os=win&lang=${AB_CD}&product=firefox-beta-latest" 235!define URLStubDownloadAMD64 "https://download.mozilla.org/?os=win64&lang=${AB_CD}&product=firefox-beta-latest" 236!define URLStubDownloadAArch64 "https://download.mozilla.org/?os=win64-aarch64&lang=${AB_CD}&product=firefox-beta-latest" 237!undef URLManualDownload 238!define URLManualDownload "https://www.mozilla.org/${AB_CD}/firefox/installer-help/?channel=beta&installer_lang=${AB_CD}" 239!undef Channel 240!define Channel "beta" 241!endif 242!endif 243 244!include "common.nsh" 245 246!insertmacro CopyPostSigningData 247!insertmacro ElevateUAC 248!insertmacro GetLongPath 249!insertmacro GetPathFromString 250!insertmacro GetParent 251!insertmacro GetSingleInstallPath 252!insertmacro InitHashAppModelId 253!insertmacro IsUserAdmin 254!insertmacro RemovePrecompleteEntries 255!insertmacro SetBrandNameVars 256!insertmacro ITBL3Create 257!insertmacro UnloadUAC 258 259VIAddVersionKey "FileDescription" "${BrandShortName} Installer" 260VIAddVersionKey "OriginalFilename" "setup-stub.exe" 261 262Name "$BrandFullName" 263OutFile "setup-stub.exe" 264Icon "firefox64.ico" 265XPStyle on 266BrandingText " " 267ChangeUI IDD_INST "nsisui.exe" 268 269!ifdef ${AB_CD}_rtl 270 LoadLanguageFile "locale-rtl.nlf" 271!else 272 LoadLanguageFile "locale.nlf" 273!endif 274 275!include "nsisstrings.nlf" 276 277Caption "$(INSTALLER_WIN_CAPTION)" 278 279Page custom createProfileCleanup 280Page custom createInstall ; Download / Installation page 281 282Function .onInit 283 ; Remove the current exe directory from the search order. 284 ; This only effects LoadLibrary calls and not implicitly loaded DLLs. 285 System::Call 'kernel32::SetDllDirectoryW(w "")' 286 287 StrCpy $LANGUAGE 0 288 ; This macro is used to set the brand name variables but the ini file method 289 ; isn't supported for the stub installer. 290 ${SetBrandNameVars} "$PLUGINSDIR\ignored.ini" 291 292 ; Don't install on systems that don't support SSE2. The parameter value of 293 ; 10 is for PF_XMMI64_INSTRUCTIONS_AVAILABLE which will check whether the 294 ; SSE2 instruction set is available. 295 System::Call "kernel32::IsProcessorFeaturePresent(i 10)i .R7" 296 297 ; Windows NT 6.0 (Vista/Server 2008) and lower are not supported. 298 ${Unless} ${AtLeastWin7} 299 ${If} "$R7" == "0" 300 strCpy $R7 "$(WARN_MIN_SUPPORTED_OSVER_CPU_MSG)" 301 ${Else} 302 strCpy $R7 "$(WARN_MIN_SUPPORTED_OSVER_MSG)" 303 ${EndIf} 304 MessageBox MB_OKCANCEL|MB_ICONSTOP "$R7" IDCANCEL +2 305 ExecShell "open" "${URLSystemRequirements}" 306 Quit 307 ${EndUnless} 308 309 ; SSE2 CPU support 310 ${If} "$R7" == "0" 311 MessageBox MB_OKCANCEL|MB_ICONSTOP "$(WARN_MIN_SUPPORTED_CPU_MSG)" IDCANCEL +2 312 ExecShell "open" "${URLSystemRequirements}" 313 Quit 314 ${EndIf} 315 316 Call GetArchToInstall 317 ${If} $ArchToInstall == ${ARCH_AARCH64} 318 ${OrIf} $ArchToInstall == ${ARCH_AMD64} 319 StrCpy $INSTDIR "${DefaultInstDir64bit}" 320 ${Else} 321 StrCpy $INSTDIR "${DefaultInstDir32bit}" 322 ${EndIf} 323 324 ; Require elevation if the user can elevate 325 ${ElevateUAC} 326 327 ; If we have any existing installation, use its location as the default 328 ; path for this install, even if it's not the same architecture. 329 SetRegView 32 330 SetShellVarContext all ; Set SHCTX to HKLM 331 ${GetSingleInstallPath} "Software\Mozilla\${BrandFullNameInternal}" $R9 332 333 ${If} "$R9" == "false" 334 ${If} ${IsNativeAMD64} 335 ${OrIf} ${IsNativeARM64} 336 SetRegView 64 337 ${GetSingleInstallPath} "Software\Mozilla\${BrandFullNameInternal}" $R9 338 ${EndIf} 339 ${EndIf} 340 341 ${If} "$R9" == "false" 342 SetShellVarContext current ; Set SHCTX to HKCU 343 ${GetSingleInstallPath} "Software\Mozilla\${BrandFullNameInternal}" $R9 344 ${EndIf} 345 346 StrCpy $PreviousInstallDir "" 347 ${If} "$R9" != "false" 348 StrCpy $PreviousInstallDir "$R9" 349 StrCpy $INSTDIR "$PreviousInstallDir" 350 ${EndIf} 351 352 ; Used to determine if the default installation directory was used. 353 StrCpy $InitialInstallDir "$INSTDIR" 354 355 ClearErrors 356 WriteRegStr HKLM "Software\Mozilla" "${BrandShortName}InstallerTest" \ 357 "Write Test" 358 359 ; Only display set as default when there is write access to HKLM and on Win7 360 ; and below. 361 ${If} ${Errors} 362 ${OrIf} ${AtLeastWin8} 363 StrCpy $CanSetAsDefault "false" 364 ${Else} 365 DeleteRegValue HKLM "Software\Mozilla" "${BrandShortName}InstallerTest" 366 StrCpy $CanSetAsDefault "true" 367 ${EndIf} 368 StrCpy $CheckboxSetAsDefault "0" 369 370 ; Initialize the majority of variables except those that need to be reset 371 ; when a page is displayed. 372 StrCpy $ExitCode "${ERR_DOWNLOAD_CANCEL}" 373 StrCpy $IntroPhaseSeconds "0" 374 StrCpy $OptionsPhaseSeconds "0" 375 StrCpy $EndPreInstallPhaseTickCount "0" 376 StrCpy $EndInstallPhaseTickCount "0" 377 StrCpy $StartDownloadPhaseTickCount "0" 378 StrCpy $EndDownloadPhaseTickCount "0" 379 StrCpy $InitialInstallRequirementsCode "" 380 StrCpy $IsDownloadFinished "" 381 StrCpy $FirefoxLaunchCode "0" 382 StrCpy $CheckboxShortcuts "1" 383 StrCpy $CheckboxSendPing "1" 384 StrCpy $CheckboxCleanupProfile "0" 385 StrCpy $ProgressCompleted "0" 386!ifdef MOZ_MAINTENANCE_SERVICE 387 ; We can only install the maintenance service if the user is an admin. 388 Call IsUserAdmin 389 Pop $0 390 ${If} "$0" == "true" 391 StrCpy $CheckboxInstallMaintSvc "1" 392 ${Else} 393 StrCpy $CheckboxInstallMaintSvc "0" 394 ${EndIf} 395!else 396 StrCpy $CheckboxInstallMaintSvc "0" 397!endif 398 399 StrCpy $FontFamilyName "" 400!ifdef FONT_FILE1 401 ${If} ${FileExists} "$FONTS\${FONT_FILE1}" 402 StrCpy $FontFamilyName "${FONT_NAME1}" 403 ${EndIf} 404!endif 405 406!ifdef FONT_FILE2 407 ${If} $FontFamilyName == "" 408 ${AndIf} ${FileExists} "$FONTS\${FONT_FILE2}" 409 StrCpy $FontFamilyName "${FONT_NAME2}" 410 ${EndIf} 411!endif 412 413 ${If} $FontFamilyName == "" 414 StrCpy $FontFamilyName "$(^Font)" 415 ${EndIf} 416 417 InitPluginsDir 418 File /oname=$PLUGINSDIR\bgstub.jpg "bgstub.jpg" 419 420 ; Detect whether the machine is running with a high contrast theme. 421 ; We'll hide our background images in that case, both because they don't 422 ; always render properly and also to improve the contrast. 423 System::Call '*(i 12, i 0, p 0) p . r0' 424 ; 0x42 == SPI_GETHIGHCONTRAST 425 System::Call 'user32::SystemParametersInfoW(i 0x42, i 0, p r0, i 0)' 426 System::Call '*$0(i, i . r1, p)' 427 System::Free $0 428 IntOp $UsingHighContrastMode $1 & 1 429 430 SetShellVarContext all ; Set SHCTX to All Users 431 ; If the user doesn't have write access to the installation directory set 432 ; the installation directory to a subdirectory of the All Users application 433 ; directory and if the user can't write to that location set the installation 434 ; directory to a subdirectory of the users local application directory 435 ; (e.g. non-roaming). 436 Call CanWrite 437 ${If} "$CanWriteToInstallDir" == "false" 438 StrCpy $INSTDIR "$APPDATA\${BrandFullName}\" 439 Call CanWrite 440 ${If} "$CanWriteToInstallDir" == "false" 441 ; This should never happen but just in case. 442 StrCpy $CanWriteToInstallDir "false" 443 ${Else} 444 StrCpy $INSTDIR "$LOCALAPPDATA\${BrandFullName}\" 445 Call CanWrite 446 ${EndIf} 447 ${EndIf} 448 449 Call CheckSpace 450 451 ${If} ${FileExists} "$INSTDIR" 452 ; Always display the long path if the path exists. 453 ${GetLongPath} "$INSTDIR" $INSTDIR 454 ${EndIf} 455 456 ; Check whether the install requirements are satisfied using the default 457 ; values for metrics. 458 ${If} "$InitialInstallRequirementsCode" == "" 459 ${If} "$CanWriteToInstallDir" != "true" 460 ${AndIf} "$HasRequiredSpaceAvailable" != "true" 461 StrCpy $InitialInstallRequirementsCode "1" 462 ${ElseIf} "$CanWriteToInstallDir" != "true" 463 StrCpy $InitialInstallRequirementsCode "2" 464 ${ElseIf} "$HasRequiredSpaceAvailable" != "true" 465 StrCpy $InitialInstallRequirementsCode "3" 466 ${Else} 467 StrCpy $InitialInstallRequirementsCode "0" 468 ${EndIf} 469 ${EndIf} 470 471 Call CanWrite 472 ${If} "$CanWriteToInstallDir" == "false" 473 MessageBox MB_OK|MB_ICONEXCLAMATION "$(WARN_WRITE_ACCESS_QUIT)$\n$\n$INSTDIR" 474 Quit 475 ${EndIf} 476 477 Call CheckSpace 478 ${If} "$HasRequiredSpaceAvailable" == "false" 479 MessageBox MB_OK|MB_ICONEXCLAMATION "$(WARN_DISK_SPACE_QUIT)" 480 Quit 481 ${EndIf} 482 483 ${InitHashAppModelId} "$INSTDIR" "Software\Mozilla\${AppName}\TaskBarIDs" 484 485 File /oname=$PLUGINSDIR\stub_common.css "stub_common.css" 486 File /oname=$PLUGINSDIR\stub_common.js "stub_common.js" 487FunctionEnd 488 489; .onGUIInit isn't needed except for RTL locales 490!ifdef ${AB_CD}_rtl 491Function .onGUIInit 492 ${MakeWindowRTL} $HWNDPARENT 493FunctionEnd 494!endif 495 496Function .onGUIEnd 497 Delete "$PLUGINSDIR\_temp" 498 Delete "$PLUGINSDIR\download.exe" 499 Delete "$PLUGINSDIR\${CONFIG_INI}" 500 501 ${UnloadUAC} 502FunctionEnd 503 504Function .onUserAbort 505 WebBrowser::CancelTimer $TimerHandle 506 507 ${If} "$IsDownloadFinished" != "" 508 ; Go ahead and cancel the download so it doesn't keep running while this 509 ; prompt is up. We'll resume it if the user decides to continue. 510 InetBgDL::Get /RESET /END 511 512 ${ShowTaskDialog} $(STUB_CANCEL_PROMPT_HEADING) \ 513 $(STUB_CANCEL_PROMPT_MESSAGE) \ 514 $(STUB_CANCEL_PROMPT_BUTTON_CONTINUE) \ 515 $(STUB_CANCEL_PROMPT_BUTTON_EXIT) 516 Pop $0 517 ${If} $0 == 1002 518 ; The cancel button was clicked 519 Call LaunchHelpPage 520 Call SendPing 521 ${Else} 522 ; Either the continue button was clicked or the dialog was dismissed 523 Call StartDownload 524 ${EndIf} 525 ${Else} 526 Call SendPing 527 ${EndIf} 528 529 ; Aborting the abort will allow SendPing to hide the installer window and 530 ; close the installer after it sends the metrics ping, or allow us to just go 531 ; back to installing if that's what the user selected. 532 Abort 533FunctionEnd 534 535!macro _RegisterAllCustomFunctions 536 GetFunctionAddress $0 getUIString 537 WebBrowser::RegisterCustomFunction $0 "getUIString" 538 539 GetFunctionAddress $0 getTextDirection 540 WebBrowser::RegisterCustomFunction $0 "getTextDirection" 541 542 GetFunctionAddress $0 getFontName 543 WebBrowser::RegisterCustomFunction $0 "getFontName" 544 545 GetFunctionAddress $0 getIsHighContrast 546 WebBrowser::RegisterCustomFunction $0 "getIsHighContrast" 547 548 GetFunctionAddress $0 gotoInstallPage 549 WebBrowser::RegisterCustomFunction $0 "gotoInstallPage" 550 551 GetFunctionAddress $0 getProgressBarPercent 552 WebBrowser::RegisterCustomFunction $0 "getProgressBarPercent" 553!macroend 554!define RegisterAllCustomFunctions "!insertmacro _RegisterAllCustomFunctions" 555 556!macro _StartTimer _INTERVAL_MS _FUNCTION_NAME 557 Push $0 558 GetFunctionAddress $0 ${_FUNCTION_NAME} 559 WebBrowser::CreateTimer $0 ${_INTERVAL_MS} 560 Pop $TimerHandle 561 Pop $0 562!macroend 563!define StartTimer "!insertmacro _StartTimer" 564 565Function gotoInstallPage 566 Pop $0 567 StrCpy $CheckboxCleanupProfile $0 568 569 StrCpy $R9 1 570 Call RelativeGotoPage 571 Push $0 572FunctionEnd 573 574Function getProgressBarPercent 575 ; Custom functions always get one parameter, which we don't use here. 576 ; But we will use $0 as a scratch accumulator register. 577 Pop $0 578 ; This math is getting the progess bar completion fraction and converting it 579 ; to a percentage, but we implement that with the operations in the reverse 580 ; of the intuitive order so that our integer math doesn't truncate to zero. 581 IntOp $0 $ProgressCompleted * 100 582 IntOp $0 $0 / ${PROGRESS_BAR_TOTAL_STEPS} 583 Push $0 584FunctionEnd 585 586Function getTextDirection 587 Pop $0 588 !ifdef ${AB_CD}_rtl 589 Push "rtl" 590 !else 591 Push "ltr" 592 !endif 593FunctionEnd 594 595Function getFontName 596 Pop $0 597 Push $FontFamilyName 598FunctionEnd 599 600Function getIsHighContrast 601 Pop $0 602 Push $UsingHighContrastMode 603FunctionEnd 604 605Function getUIString 606 Pop $0 607 ${Select} $0 608 ${Case} "cleanup_header" 609 ${If} $ProfileCleanupPromptType == 1 610 Push "$(STUB_CLEANUP_REINSTALL_HEADER2)" 611 ${Else} 612 Push "$(STUB_CLEANUP_PAVEOVER_HEADER2)" 613 ${EndIf} 614 ${Case} "cleanup_button" 615 ${If} $ProfileCleanupPromptType == 1 616 Push "$(STUB_CLEANUP_REINSTALL_BUTTON2)" 617 ${Else} 618 Push "$(STUB_CLEANUP_PAVEOVER_BUTTON2)" 619 ${EndIf} 620 ${Case} "cleanup_checkbox" 621 Push "$(STUB_CLEANUP_CHECKBOX_LABEL2)" 622 ${Case} "installing_header" 623 Push "$(STUB_INSTALLING_HEADLINE2)" 624 ${Case} "installing_label" 625 Push "$(STUB_INSTALLING_LABEL2)" 626 ${Case} "installing_content" 627 Push "$(STUB_INSTALLING_BODY2)" 628 ${Case} "installing_blurb_0" 629 Push "$(STUB_BLURB_FIRST1)" 630 ${Case} "installing_blurb_1" 631 Push "$(STUB_BLURB_SECOND1)" 632 ${Case} "installing_blurb_2" 633 Push "$(STUB_BLURB_THIRD1)" 634 ${Case} "global_footer" 635 Push "$(STUB_BLURB_FOOTER2)" 636 ${Default} 637 Push "" 638 ${EndSelect} 639FunctionEnd 640 641Function createProfileCleanup 642 Call ShouldPromptForProfileCleanup 643 644 ${If} $ProfileCleanupPromptType == 0 645 StrCpy $CheckboxCleanupProfile 0 646 Abort ; Skip this page 647 ${EndIf} 648 649 ${RegisterAllCustomFunctions} 650 651 File /oname=$PLUGINSDIR\profile_cleanup.html "profile_cleanup.html" 652 File /oname=$PLUGINSDIR\profile_cleanup_page.css "profile_cleanup_page.css" 653 File /oname=$PLUGINSDIR\profile_cleanup.js "profile_cleanup.js" 654 WebBrowser::ShowPage "$PLUGINSDIR\profile_cleanup.html" 655FunctionEnd 656 657Function createInstall 658 GetDlgItem $0 $HWNDPARENT 1 ; Install button 659 EnableWindow $0 0 660 ShowWindow $0 ${SW_HIDE} 661 662 GetDlgItem $0 $HWNDPARENT 3 ; Back button 663 EnableWindow $0 0 664 ShowWindow $0 ${SW_HIDE} 665 666 GetDlgItem $0 $HWNDPARENT 2 ; Cancel button 667 ; Hide the Cancel button, but don't disable it (or else it won't be possible 668 ; to close the window) 669 ShowWindow $0 ${SW_HIDE} 670 671 ; Get keyboard focus on the parent 672 System::Call "user32::SetFocus(p$HWNDPARENT)" 673 674 ; Set $DownloadReset to true so the first download tick count is measured. 675 StrCpy $DownloadReset "true" 676 StrCpy $IsDownloadFinished "false" 677 StrCpy $DownloadRetryCount "0" 678 StrCpy $DownloadedBytes "0" 679 StrCpy $StartLastDownloadTickCount "" 680 StrCpy $DownloadFirstTransferSeconds "" 681 StrCpy $OpenedDownloadPage "0" 682 683 ClearErrors 684 ReadINIStr $ExistingVersion "$INSTDIR\application.ini" "App" "Version" 685 ${If} ${Errors} 686 StrCpy $ExistingVersion "0" 687 ${EndIf} 688 689 ClearErrors 690 ReadINIStr $ExistingBuildID "$INSTDIR\application.ini" "App" "BuildID" 691 ${If} ${Errors} 692 StrCpy $ExistingBuildID "0" 693 ${EndIf} 694 695 ${If} ${FileExists} "$LOCALAPPDATA\Mozilla\Firefox" 696 StrCpy $ExistingProfile "1" 697 ${Else} 698 StrCpy $ExistingProfile "0" 699 ${EndIf} 700 701 StrCpy $DownloadServerIP "" 702 703 System::Call "kernel32::GetTickCount()l .s" 704 Pop $StartDownloadPhaseTickCount 705 706 ${If} ${FileExists} "$INSTDIR\uninstall\uninstall.log" 707 StrCpy $InstallTotalSteps ${InstallPaveOverTotalSteps} 708 ${Else} 709 StrCpy $InstallTotalSteps ${InstallCleanTotalSteps} 710 ${EndIf} 711 712 ${ITBL3Create} 713 ${ITBL3SetProgressState} "${TBPF_INDETERMINATE}" 714 715 ; Make sure the file we're about to try to download to doesn't already exist, 716 ; so we don't end up trying to "resume" on top of the wrong file. 717 Delete "$PLUGINSDIR\download.exe" 718 719 ${StartTimer} ${DownloadIntervalMS} StartDownload 720 721 ${RegisterAllCustomFunctions} 722 723 File /oname=$PLUGINSDIR\installing.html "installing.html" 724 File /oname=$PLUGINSDIR\installing_page.css "installing_page.css" 725 File /oname=$PLUGINSDIR\installing.js "installing.js" 726 WebBrowser::ShowPage "$PLUGINSDIR\installing.html" 727FunctionEnd 728 729Function StartDownload 730 WebBrowser::CancelTimer $TimerHandle 731 732 Call GetDownloadURL 733 Pop $0 734 InetBgDL::Get "$0" "$PLUGINSDIR\download.exe" \ 735 /CONNECTTIMEOUT 120 /RECEIVETIMEOUT 120 /END 736 737 ${StartTimer} ${DownloadIntervalMS} OnDownload 738 739 ${If} ${FileExists} "$INSTDIR\${TO_BE_DELETED}" 740 RmDir /r "$INSTDIR\${TO_BE_DELETED}" 741 ${EndIf} 742FunctionEnd 743 744Function SetProgressBars 745 ${ITBL3SetProgressValue} "$ProgressCompleted" "${PROGRESS_BAR_TOTAL_STEPS}" 746FunctionEnd 747 748Function OnDownload 749 InetBgDL::GetStats 750 # $0 = HTTP status code, 0=Completed 751 # $1 = Completed files 752 # $2 = Remaining files 753 # $3 = Number of downloaded bytes for the current file 754 # $4 = Size of current file (Empty string if the size is unknown) 755 # /RESET must be used if status $0 > 299 (e.g. failure), even if resuming 756 # When status is $0 =< 299 it is handled by InetBgDL 757 StrCpy $DownloadServerIP "$5" 758 ${If} $0 > 299 759 WebBrowser::CancelTimer $TimerHandle 760 IntOp $DownloadRetryCount $DownloadRetryCount + 1 761 ${If} $DownloadRetryCount >= ${DownloadMaxRetries} 762 StrCpy $ExitCode "${ERR_DOWNLOAD_TOO_MANY_RETRIES}" 763 ; Use a timer so the UI has a chance to update 764 ${StartTimer} ${InstallIntervalMS} DisplayDownloadError 765 Return 766 ${EndIf} 767 768 ; 1000 is a special code meaning InetBgDL lost the connection before it got 769 ; all the bytes it was expecting. We'll try to resume the transfer in that 770 ; case (assuming we aren't out of retries), so don't treat it as a reset 771 ; or clear the progress bar. 772 ${If} $0 != 1000 773 ${If} "$DownloadReset" != "true" 774 StrCpy $DownloadedBytes "0" 775 ${ITBL3SetProgressState} "${TBPF_INDETERMINATE}" 776 ${EndIf} 777 StrCpy $DownloadSizeBytes "" 778 StrCpy $DownloadReset "true" 779 Delete "$PLUGINSDIR\download.exe" 780 ${EndIf} 781 782 InetBgDL::Get /RESET /END 783 ${StartTimer} ${DownloadRetryIntervalMS} StartDownload 784 Return 785 ${EndIf} 786 787 ${If} "$DownloadReset" == "true" 788 System::Call "kernel32::GetTickCount()l .s" 789 Pop $StartLastDownloadTickCount 790 StrCpy $DownloadReset "false" 791 ; The seconds elapsed from the start of the download phase until the first 792 ; bytes are received are only recorded for the first request so it is 793 ; possible to determine connection issues for the first request. 794 ${If} "$DownloadFirstTransferSeconds" == "" 795 ; Get the seconds elapsed from the start of the download phase until the 796 ; first bytes are received. 797 ${GetSecondsElapsed} "$StartDownloadPhaseTickCount" "$StartLastDownloadTickCount" $DownloadFirstTransferSeconds 798 ${EndIf} 799 ${EndIf} 800 801 ${If} "$DownloadSizeBytes" == "" 802 ${AndIf} "$4" != "" 803 StrCpy $DownloadSizeBytes "$4" 804 StrCpy $ProgressCompleted 0 805 ${EndIf} 806 807 ; Don't update the status until after the download starts 808 ${If} $2 != 0 809 ${AndIf} "$4" == "" 810 Return 811 ${EndIf} 812 813 ${If} $IsDownloadFinished != "true" 814 ${If} $2 == 0 815 WebBrowser::CancelTimer $TimerHandle 816 StrCpy $IsDownloadFinished "true" 817 System::Call "kernel32::GetTickCount()l .s" 818 Pop $EndDownloadPhaseTickCount 819 820 ${If} "$DownloadSizeBytes" == "" 821 ; It's possible for the download to finish before we were able to 822 ; get the size while it was downloading, and InetBgDL doesn't report 823 ; it afterwards. Use the size of the finished file. 824 ClearErrors 825 FileOpen $5 "$PLUGINSDIR\download.exe" r 826 ${IfNot} ${Errors} 827 FileSeek $5 0 END $DownloadSizeBytes 828 FileClose $5 829 ${EndIf} 830 ${EndIf} 831 StrCpy $DownloadedBytes "$DownloadSizeBytes" 832 833 ; Update the progress bars first in the UI change so they take affect 834 ; before other UI changes. 835 StrCpy $ProgressCompleted "${PROGRESS_BAR_DOWNLOAD_END_STEP}" 836 Call SetProgressBars 837 838 ; Disable the Cancel button during the install 839 GetDlgItem $5 $HWNDPARENT 2 840 EnableWindow $5 0 841 842 ; Open a handle to prevent modification of the full installer 843 StrCpy $R9 "${INVALID_HANDLE_VALUE}" 844 System::Call 'kernel32::CreateFileW(w "$PLUGINSDIR\download.exe", \ 845 i ${GENERIC_READ}, \ 846 i ${FILE_SHARE_READ}, i 0, \ 847 i ${OPEN_EXISTING}, i 0, i 0) i .R9' 848 StrCpy $HandleDownload "$R9" 849 850 ${If} $HandleDownload == ${INVALID_HANDLE_VALUE} 851 StrCpy $ExitCode "${ERR_PREINSTALL_INVALID_HANDLE}" 852 System::Call "kernel32::GetTickCount()l .s" 853 Pop $EndPreInstallPhaseTickCount 854 ; Use a timer so the UI has a chance to update 855 ${StartTimer} ${InstallIntervalMS} DisplayDownloadError 856 ${Else} 857 CertCheck::CheckPETrustAndInfoAsync "$PLUGINSDIR\download.exe" \ 858 "${CertNameDownload}" "${CertIssuerDownload}" 859 ${StartTimer} ${DownloadIntervalMS} OnCertCheck 860 ${EndIf} 861 ${Else} 862 StrCpy $DownloadedBytes "$3" 863 System::Int64Op $DownloadedBytes * ${PROGRESS_BAR_DOWNLOAD_END_STEP} 864 Pop $ProgressCompleted 865 System::Int64Op $ProgressCompleted / $DownloadSizeBytes 866 Pop $ProgressCompleted 867 Call SetProgressBars 868 ${EndIf} 869 ${EndIf} 870FunctionEnd 871 872Function OnCertCheck 873 System::Call "kernel32::GetTickCount()l .s" 874 Pop $EndPreInstallPhaseTickCount 875 876 CertCheck::GetStatus 877 Pop $0 878 ${If} $0 == 0 879 ${GetSecondsElapsed} "$EndDownloadPhaseTickCount" "$EndPreInstallPhaseTickCount" $0 880 ${If} $0 >= ${PreinstallCertCheckMaxWaitSec} 881 WebBrowser::CancelTimer $TimerHandle 882 StrCpy $ExitCode "${ERR_PREINSTALL_CERT_TIMEOUT}" 883 ; Use a timer so the UI has a chance to update 884 ${StartTimer} ${InstallIntervalMS} DisplayDownloadError 885 ${EndIf} 886 Return 887 ${EndIf} 888 Pop $0 889 Pop $1 890 891 ${If} $0 == 0 892 ${AndIf} $1 == 0 893 StrCpy $ExitCode "${ERR_PREINSTALL_CERT_UNTRUSTED_AND_ATTRIBUTES}" 894 ${ElseIf} $0 == 0 895 StrCpy $ExitCode "${ERR_PREINSTALL_CERT_UNTRUSTED}" 896 ${ElseIf} $1 == 0 897 StrCpy $ExitCode "${ERR_PREINSTALL_CERT_ATTRIBUTES}" 898 ${EndIf} 899 900 WebBrowser::CancelTimer $TimerHandle 901 902 ${If} $0 == 0 903 ${OrIf} $1 == 0 904 ; Use a timer so the UI has a chance to update 905 ${StartTimer} ${InstallIntervalMS} DisplayDownloadError 906 Return 907 ${EndIf} 908 909 Call LaunchFullInstaller 910FunctionEnd 911 912Function LaunchFullInstaller 913 ; Instead of extracting the files we use the downloaded installer to 914 ; install in case it needs to perform operations that the stub doesn't 915 ; know about. 916 WriteINIStr "$PLUGINSDIR\${CONFIG_INI}" "Install" "InstallDirectoryPath" "$INSTDIR" 917 ; Don't create the QuickLaunch or Taskbar shortcut from the launched installer 918 WriteINIStr "$PLUGINSDIR\${CONFIG_INI}" "Install" "QuickLaunchShortcut" "false" 919 920 ; Always create a start menu shortcut, so the user always has some way 921 ; to access the application. 922 WriteINIStr "$PLUGINSDIR\${CONFIG_INI}" "Install" "StartMenuShortcuts" "true" 923 924 ; Either avoid or force adding a taskbar pin and desktop shortcut 925 ; based on the checkbox value. 926 ${If} $CheckboxShortcuts == 0 927 WriteINIStr "$PLUGINSDIR\${CONFIG_INI}" "Install" "TaskbarShortcut" "false" 928 WriteINIStr "$PLUGINSDIR\${CONFIG_INI}" "Install" "DesktopShortcut" "false" 929 ${Else} 930 WriteINIStr "$PLUGINSDIR\${CONFIG_INI}" "Install" "TaskbarShortcut" "true" 931 WriteINIStr "$PLUGINSDIR\${CONFIG_INI}" "Install" "DesktopShortcut" "true" 932 ${EndIf} 933 934!ifdef MOZ_MAINTENANCE_SERVICE 935 ${If} $CheckboxInstallMaintSvc == 1 936 WriteINIStr "$PLUGINSDIR\${CONFIG_INI}" "Install" "MaintenanceService" "true" 937 ${Else} 938 WriteINIStr "$PLUGINSDIR\${CONFIG_INI}" "Install" "MaintenanceService" "false" 939 ${EndIf} 940!else 941 WriteINIStr "$PLUGINSDIR\${CONFIG_INI}" "Install" "MaintenanceService" "false" 942!endif 943 944 ; Delete the taskbar shortcut history to ensure we do the right thing based on 945 ; the config file above. 946 ${GetShortcutsLogPath} $0 947 Delete "$0" 948 949 ${RemovePrecompleteEntries} "false" 950 951 ; Delete the install.log and let the full installer create it. When the 952 ; installer closes it we can detect that it has completed. 953 Delete "$INSTDIR\install.log" 954 955 ; Delete firefox.exe.moz-upgrade and firefox.exe.moz-delete if it exists 956 ; since it being present will require an OS restart for the full 957 ; installer. 958 Delete "$INSTDIR\${FileMainEXE}.moz-upgrade" 959 Delete "$INSTDIR\${FileMainEXE}.moz-delete" 960 961 System::Call "kernel32::GetTickCount()l .s" 962 Pop $EndPreInstallPhaseTickCount 963 964 Exec "$\"$PLUGINSDIR\download.exe$\" /LaunchedFromStub /INI=$PLUGINSDIR\${CONFIG_INI}" 965 ${StartTimer} ${InstallIntervalMS} CheckInstall 966FunctionEnd 967 968Function SendPing 969 HideWindow 970 971 ${If} $CheckboxSendPing == 1 972 ; Get the tick count for the completion of all phases. 973 System::Call "kernel32::GetTickCount()l .s" 974 Pop $EndFinishPhaseTickCount 975 976 ; When the value of $IsDownloadFinished is false the download was started 977 ; but didn't finish. In this case the tick count stored in 978 ; $EndFinishPhaseTickCount is used to determine how long the download was 979 ; in progress. 980 ${If} "$IsDownloadFinished" == "false" 981 StrCpy $EndDownloadPhaseTickCount "$EndFinishPhaseTickCount" 982 ; Cancel the download in progress 983 InetBgDL::Get /RESET /END 984 ${EndIf} 985 986 987 ; When $DownloadFirstTransferSeconds equals an empty string the download 988 ; never successfully started so set the value to 0. It will be possible to 989 ; determine that the download didn't successfully start from the seconds for 990 ; the last download. 991 ${If} "$DownloadFirstTransferSeconds" == "" 992 StrCpy $DownloadFirstTransferSeconds "0" 993 ${EndIf} 994 995 ; When $StartLastDownloadTickCount equals an empty string the download never 996 ; successfully started so set the value to $EndDownloadPhaseTickCount to 997 ; compute the correct value. 998 ${If} $StartLastDownloadTickCount == "" 999 ; This could happen if the download never successfully starts 1000 StrCpy $StartLastDownloadTickCount "$EndDownloadPhaseTickCount" 1001 ${EndIf} 1002 1003 ; When $EndPreInstallPhaseTickCount equals 0 the installation phase was 1004 ; never completed so set its value to $EndFinishPhaseTickCount to compute 1005 ; the correct value. 1006 ${If} "$EndPreInstallPhaseTickCount" == "0" 1007 StrCpy $EndPreInstallPhaseTickCount "$EndFinishPhaseTickCount" 1008 ${EndIf} 1009 1010 ; When $EndInstallPhaseTickCount equals 0 the installation phase was never 1011 ; completed so set its value to $EndFinishPhaseTickCount to compute the 1012 ; correct value. 1013 ${If} "$EndInstallPhaseTickCount" == "0" 1014 StrCpy $EndInstallPhaseTickCount "$EndFinishPhaseTickCount" 1015 ${EndIf} 1016 1017 ; Get the seconds elapsed from the start of the download phase to the end of 1018 ; the download phase. 1019 ${GetSecondsElapsed} "$StartDownloadPhaseTickCount" "$EndDownloadPhaseTickCount" $0 1020 1021 ; Get the seconds elapsed from the start of the last download to the end of 1022 ; the last download. 1023 ${GetSecondsElapsed} "$StartLastDownloadTickCount" "$EndDownloadPhaseTickCount" $1 1024 1025 ; Get the seconds elapsed from the end of the download phase to the 1026 ; completion of the pre-installation check phase. 1027 ${GetSecondsElapsed} "$EndDownloadPhaseTickCount" "$EndPreInstallPhaseTickCount" $2 1028 1029 ; Get the seconds elapsed from the end of the pre-installation check phase 1030 ; to the completion of the installation phase. 1031 ${GetSecondsElapsed} "$EndPreInstallPhaseTickCount" "$EndInstallPhaseTickCount" $3 1032 1033 ; Get the seconds elapsed from the end of the installation phase to the 1034 ; completion of all phases. 1035 ${GetSecondsElapsed} "$EndInstallPhaseTickCount" "$EndFinishPhaseTickCount" $4 1036 1037 ${If} $ArchToInstall == ${ARCH_AMD64} 1038 ${OrIf} $ArchToInstall == ${ARCH_AARCH64} 1039 StrCpy $R0 "1" 1040 ${Else} 1041 StrCpy $R0 "0" 1042 ${EndIf} 1043 1044 ${If} ${IsNativeAMD64} 1045 ${OrIf} ${IsNativeARM64} 1046 StrCpy $R1 "1" 1047 ${Else} 1048 StrCpy $R1 "0" 1049 ${EndIf} 1050 1051 ; Though these values are sometimes incorrect due to bug 444664 it happens 1052 ; so rarely it isn't worth working around it by reading the registry values. 1053 ${WinVerGetMajor} $5 1054 ${WinVerGetMinor} $6 1055 ${WinVerGetBuild} $7 1056 ${WinVerGetServicePackLevel} $8 1057 ${If} ${IsServerOS} 1058 StrCpy $9 "1" 1059 ${Else} 1060 StrCpy $9 "0" 1061 ${EndIf} 1062 1063 ${If} "$ExitCode" == "${ERR_SUCCESS}" 1064 ReadINIStr $R5 "$INSTDIR\application.ini" "App" "Version" 1065 ReadINIStr $R6 "$INSTDIR\application.ini" "App" "BuildID" 1066 ${Else} 1067 StrCpy $R5 "0" 1068 StrCpy $R6 "0" 1069 ${EndIf} 1070 1071 ; Whether installed into the default installation directory 1072 ${GetLongPath} "$INSTDIR" $R7 1073 ${GetLongPath} "$InitialInstallDir" $R8 1074 ${If} "$R7" == "$R8" 1075 StrCpy $R7 "1" 1076 ${Else} 1077 StrCpy $R7 "0" 1078 ${EndIf} 1079 1080 ClearErrors 1081 WriteRegStr HKLM "Software\Mozilla" "${BrandShortName}InstallerTest" \ 1082 "Write Test" 1083 ${If} ${Errors} 1084 StrCpy $R8 "0" 1085 ${Else} 1086 DeleteRegValue HKLM "Software\Mozilla" "${BrandShortName}InstallerTest" 1087 StrCpy $R8 "1" 1088 ${EndIf} 1089 1090 ${If} "$DownloadServerIP" == "" 1091 StrCpy $DownloadServerIP "Unknown" 1092 ${EndIf} 1093 1094 StrCpy $R2 "" 1095 SetShellVarContext current ; Set SHCTX to the current user 1096 ReadRegStr $R2 HKCU "Software\Classes\http\shell\open\command" "" 1097 ${If} $R2 != "" 1098 ${GetPathFromString} "$R2" $R2 1099 ${GetParent} "$R2" $R3 1100 ${GetLongPath} "$R3" $R3 1101 ${If} $R3 == $INSTDIR 1102 StrCpy $R2 "1" ; This Firefox install is set as default. 1103 ${Else} 1104 StrCpy $R2 "$R2" "" -11 # length of firefox.exe 1105 ${If} "$R2" == "${FileMainEXE}" 1106 StrCpy $R2 "2" ; Another Firefox install is set as default. 1107 ${Else} 1108 StrCpy $R2 "0" 1109 ${EndIf} 1110 ${EndIf} 1111 ${Else} 1112 StrCpy $R2 "0" ; Firefox is not set as default. 1113 ${EndIf} 1114 1115 ${If} "$R2" == "0" 1116 StrCpy $R3 "" 1117 ReadRegStr $R2 HKLM "Software\Classes\http\shell\open\command" "" 1118 ${If} $R2 != "" 1119 ${GetPathFromString} "$R2" $R2 1120 ${GetParent} "$R2" $R3 1121 ${GetLongPath} "$R3" $R3 1122 ${If} $R3 == $INSTDIR 1123 StrCpy $R2 "1" ; This Firefox install is set as default. 1124 ${Else} 1125 StrCpy $R2 "$R2" "" -11 # length of firefox.exe 1126 ${If} "$R2" == "${FileMainEXE}" 1127 StrCpy $R2 "2" ; Another Firefox install is set as default. 1128 ${Else} 1129 StrCpy $R2 "0" 1130 ${EndIf} 1131 ${EndIf} 1132 ${Else} 1133 StrCpy $R2 "0" ; Firefox is not set as default. 1134 ${EndIf} 1135 ${EndIf} 1136 1137 ${If} $CanSetAsDefault == "true" 1138 ${If} $CheckboxSetAsDefault == "1" 1139 StrCpy $R3 "2" 1140 ${Else} 1141 StrCpy $R3 "3" 1142 ${EndIf} 1143 ${Else} 1144 ${If} ${AtLeastWin8} 1145 StrCpy $R3 "1" 1146 ${Else} 1147 StrCpy $R3 "0" 1148 ${EndIf} 1149 ${EndIf} 1150 1151!ifdef STUB_DEBUG 1152 MessageBox MB_OK "${BaseURLStubPing} \ 1153 $\nStub URL Version = ${StubURLVersion}${StubURLVersionAppend} \ 1154 $\nBuild Channel = ${Channel} \ 1155 $\nUpdate Channel = ${UpdateChannel} \ 1156 $\nLocale = ${AB_CD} \ 1157 $\nFirefox x64 = $R0 \ 1158 $\nRunning x64 Windows = $R1 \ 1159 $\nMajor = $5 \ 1160 $\nMinor = $6 \ 1161 $\nBuild = $7 \ 1162 $\nServicePack = $8 \ 1163 $\nIsServer = $9 \ 1164 $\nExit Code = $ExitCode \ 1165 $\nFirefox Launch Code = $FirefoxLaunchCode \ 1166 $\nDownload Retry Count = $DownloadRetryCount \ 1167 $\nDownloaded Bytes = $DownloadedBytes \ 1168 $\nDownload Size Bytes = $DownloadSizeBytes \ 1169 $\nIntroduction Phase Seconds = $IntroPhaseSeconds \ 1170 $\nOptions Phase Seconds = $OptionsPhaseSeconds \ 1171 $\nDownload Phase Seconds = $0 \ 1172 $\nLast Download Seconds = $1 \ 1173 $\nDownload First Transfer Seconds = $DownloadFirstTransferSeconds \ 1174 $\nPreinstall Phase Seconds = $2 \ 1175 $\nInstall Phase Seconds = $3 \ 1176 $\nFinish Phase Seconds = $4 \ 1177 $\nInitial Install Requirements Code = $InitialInstallRequirementsCode \ 1178 $\nOpened Download Page = $OpenedDownloadPage \ 1179 $\nExisting Profile = $ExistingProfile \ 1180 $\nExisting Version = $ExistingVersion \ 1181 $\nExisting Build ID = $ExistingBuildID \ 1182 $\nNew Version = $R5 \ 1183 $\nNew Build ID = $R6 \ 1184 $\nDefault Install Dir = $R7 \ 1185 $\nHas Admin = $R8 \ 1186 $\nDefault Status = $R2 \ 1187 $\nSet As Sefault Status = $R3 \ 1188 $\nDownload Server IP = $DownloadServerIP \ 1189 $\nPost-Signing Data = $PostSigningData \ 1190 $\nProfile cleanup prompt shown = $ProfileCleanupPromptType \ 1191 $\nDid profile cleanup = $CheckboxCleanupProfile" 1192 ; The following will exit the installer 1193 SetAutoClose true 1194 StrCpy $R9 "2" 1195 Call RelativeGotoPage 1196!else 1197 ${StartTimer} ${DownloadIntervalMS} OnPing 1198 InetBgDL::Get "${BaseURLStubPing}/${StubURLVersion}${StubURLVersionAppend}/${Channel}/${UpdateChannel}/${AB_CD}/$R0/$R1/$5/$6/$7/$8/$9/$ExitCode/$FirefoxLaunchCode/$DownloadRetryCount/$DownloadedBytes/$DownloadSizeBytes/$IntroPhaseSeconds/$OptionsPhaseSeconds/$0/$1/$DownloadFirstTransferSeconds/$2/$3/$4/$InitialInstallRequirementsCode/$OpenedDownloadPage/$ExistingProfile/$ExistingVersion/$ExistingBuildID/$R5/$R6/$R7/$R8/$R2/$R3/$DownloadServerIP/$PostSigningData/$ProfileCleanupPromptType/$CheckboxCleanupProfile" \ 1199 "$PLUGINSDIR\_temp" /END 1200!endif 1201 ${Else} 1202 ${If} "$IsDownloadFinished" == "false" 1203 ; Cancel the download in progress 1204 InetBgDL::Get /RESET /END 1205 ${EndIf} 1206 ; The following will exit the installer 1207 SetAutoClose true 1208 StrCpy $R9 "2" 1209 Call RelativeGotoPage 1210 ${EndIf} 1211FunctionEnd 1212 1213Function OnPing 1214 InetBgDL::GetStats 1215 # $0 = HTTP status code, 0=Completed 1216 # $1 = Completed files 1217 # $2 = Remaining files 1218 # $3 = Number of downloaded bytes for the current file 1219 # $4 = Size of current file (Empty string if the size is unknown) 1220 # /RESET must be used if status $0 > 299 (e.g. failure) 1221 # When status is $0 =< 299 it is handled by InetBgDL 1222 ${If} $2 == 0 1223 ${OrIf} $0 > 299 1224 WebBrowser::CancelTimer $TimerHandle 1225 ${If} $0 > 299 1226 InetBgDL::Get /RESET /END 1227 ${EndIf} 1228 ; The following will exit the installer 1229 SetAutoClose true 1230 StrCpy $R9 "2" 1231 Call RelativeGotoPage 1232 ${EndIf} 1233FunctionEnd 1234 1235Function CheckInstall 1236 IntOp $InstallCounterStep $InstallCounterStep + 1 1237 ${If} $InstallCounterStep >= $InstallTotalSteps 1238 WebBrowser::CancelTimer $TimerHandle 1239 ; Close the handle that prevents modification of the full installer 1240 System::Call 'kernel32::CloseHandle(i $HandleDownload)' 1241 StrCpy $ExitCode "${ERR_INSTALL_TIMEOUT}" 1242 ; Use a timer so the UI has a chance to update 1243 ${StartTimer} ${InstallIntervalMS} DisplayDownloadError 1244 Return 1245 ${EndIf} 1246 1247 ${If} $ProgressCompleted < ${PROGRESS_BAR_INSTALL_END_STEP} 1248 IntOp $0 ${PROGRESS_BAR_INSTALL_END_STEP} - ${PROGRESS_BAR_DOWNLOAD_END_STEP} 1249 IntOp $0 $InstallCounterStep * $0 1250 IntOp $0 $0 / $InstallTotalSteps 1251 IntOp $ProgressCompleted ${PROGRESS_BAR_DOWNLOAD_END_STEP} + $0 1252 Call SetProgressBars 1253 ${EndIf} 1254 1255 ${If} ${FileExists} "$INSTDIR\install.log" 1256 Delete "$INSTDIR\install.tmp" 1257 CopyFiles /SILENT "$INSTDIR\install.log" "$INSTDIR\install.tmp" 1258 1259 ; The unfocus and refocus that happens approximately here is caused by the 1260 ; installer calling RefreshShellIcons to refresh the shortcut icons. 1261 1262 ; When the full installer completes the installation the install.log will no 1263 ; longer be in use. 1264 ClearErrors 1265 Delete "$INSTDIR\install.log" 1266 ${Unless} ${Errors} 1267 WebBrowser::CancelTimer $TimerHandle 1268 ; Close the handle that prevents modification of the full installer 1269 System::Call 'kernel32::CloseHandle(i $HandleDownload)' 1270 Rename "$INSTDIR\install.tmp" "$INSTDIR\install.log" 1271 Delete "$PLUGINSDIR\download.exe" 1272 Delete "$PLUGINSDIR\${CONFIG_INI}" 1273 System::Call "kernel32::GetTickCount()l .s" 1274 Pop $EndInstallPhaseTickCount 1275 Call FinishInstall 1276 ${EndUnless} 1277 ${EndIf} 1278FunctionEnd 1279 1280Function FinishInstall 1281 StrCpy $ProgressCompleted "${PROGRESS_BAR_INSTALL_END_STEP}" 1282 Call SetProgressBars 1283 1284 ${If} ${FileExists} "$INSTDIR\${FileMainEXE}.moz-upgrade" 1285 Delete "$INSTDIR\${FileMainEXE}" 1286 Rename "$INSTDIR\${FileMainEXE}.moz-upgrade" "$INSTDIR\${FileMainEXE}" 1287 ${EndIf} 1288 1289 StrCpy $ExitCode "${ERR_SUCCESS}" 1290 1291 ${CopyPostSigningData} 1292 Pop $PostSigningData 1293 1294 Call LaunchApp 1295FunctionEnd 1296 1297Function RelativeGotoPage 1298 IntCmp $R9 0 0 Move Move 1299 StrCmp $R9 "X" 0 Move 1300 StrCpy $R9 "120" 1301 1302 Move: 1303 SendMessage $HWNDPARENT "0x408" "$R9" "" 1304FunctionEnd 1305 1306Function CheckSpace 1307 ${If} "$ExistingTopDir" != "" 1308 StrLen $0 "$ExistingTopDir" 1309 StrLen $1 "$INSTDIR" 1310 ${If} $0 <= $1 1311 StrCpy $2 "$INSTDIR" $3 1312 ${If} "$2" == "$ExistingTopDir" 1313 Return 1314 ${EndIf} 1315 ${EndIf} 1316 ${EndIf} 1317 1318 StrCpy $ExistingTopDir "$INSTDIR" 1319 ${DoUntil} ${FileExists} "$ExistingTopDir" 1320 ${GetParent} "$ExistingTopDir" $ExistingTopDir 1321 ${If} "$ExistingTopDir" == "" 1322 StrCpy $SpaceAvailableBytes "0" 1323 StrCpy $HasRequiredSpaceAvailable "false" 1324 Return 1325 ${EndIf} 1326 ${Loop} 1327 1328 ${GetLongPath} "$ExistingTopDir" $ExistingTopDir 1329 1330 ; GetDiskFreeSpaceExW requires a backslash. 1331 StrCpy $0 "$ExistingTopDir" "" -1 ; the last character 1332 ${If} "$0" != "\" 1333 StrCpy $0 "\" 1334 ${Else} 1335 StrCpy $0 "" 1336 ${EndIf} 1337 1338 System::Call 'kernel32::GetDiskFreeSpaceExW(w, *l, *l, *l) i("$ExistingTopDir$0", .r1, .r2, .r3) .' 1339 StrCpy $SpaceAvailableBytes "$1" 1340 1341 System::Int64Op $SpaceAvailableBytes / 1048576 1342 Pop $1 1343 System::Int64Op $1 > ${APPROXIMATE_REQUIRED_SPACE_MB} 1344 Pop $1 1345 ${If} $1 == 1 1346 StrCpy $HasRequiredSpaceAvailable "true" 1347 ${Else} 1348 StrCpy $HasRequiredSpaceAvailable "false" 1349 ${EndIf} 1350FunctionEnd 1351 1352Function CanWrite 1353 StrCpy $CanWriteToInstallDir "false" 1354 1355 StrCpy $0 "$INSTDIR" 1356 ; Use the existing directory when it exists 1357 ${Unless} ${FileExists} "$INSTDIR" 1358 ; Get the topmost directory that exists for new installs 1359 ${DoUntil} ${FileExists} "$0" 1360 ${GetParent} "$0" $0 1361 ${If} "$0" == "" 1362 Return 1363 ${EndIf} 1364 ${Loop} 1365 ${EndUnless} 1366 1367 GetTempFileName $2 "$0" 1368 Delete $2 1369 CreateDirectory "$2" 1370 1371 ${If} ${FileExists} "$2" 1372 ${If} ${FileExists} "$INSTDIR" 1373 GetTempFileName $3 "$INSTDIR" 1374 ${Else} 1375 GetTempFileName $3 "$2" 1376 ${EndIf} 1377 ${If} ${FileExists} "$3" 1378 Delete "$3" 1379 StrCpy $CanWriteToInstallDir "true" 1380 ${EndIf} 1381 RmDir "$2" 1382 ${EndIf} 1383FunctionEnd 1384 1385Function LaunchApp 1386 StrCpy $FirefoxLaunchCode "2" 1387 1388 ; Set the current working directory to the installation directory 1389 SetOutPath "$INSTDIR" 1390 ClearErrors 1391 ${GetParameters} $0 1392 ${GetOptions} "$0" "/UAC:" $1 1393 ${If} ${Errors} 1394 ${If} $CheckboxCleanupProfile == 1 1395 ${ExecAndWaitForInputIdle} "$\"$INSTDIR\${FileMainEXE}$\" -reset-profile -migration -first-startup" 1396 ${Else} 1397 ${ExecAndWaitForInputIdle} "$\"$INSTDIR\${FileMainEXE}$\" -first-startup" 1398 ${EndIf} 1399 ${Else} 1400 StrCpy $R1 $CheckboxCleanupProfile 1401 GetFunctionAddress $0 LaunchAppFromElevatedProcess 1402 UAC::ExecCodeSegment $0 1403 ${EndIf} 1404 1405 StrCpy $AppLaunchWaitTickCount 0 1406 ${StartTimer} ${AppLaunchWaitIntervalMS} WaitForAppLaunch 1407FunctionEnd 1408 1409Function LaunchAppFromElevatedProcess 1410 ; Set the current working directory to the installation directory 1411 SetOutPath "$INSTDIR" 1412 ${If} $R1 == 1 1413 ${ExecAndWaitForInputIdle} "$\"$INSTDIR\${FileMainEXE}$\" -reset-profile -migration -first-startup" 1414 ${Else} 1415 ${ExecAndWaitForInputIdle} "$\"$INSTDIR\${FileMainEXE}$\" -first-startup" 1416 ${EndIf} 1417FunctionEnd 1418 1419Function WaitForAppLaunch 1420 FindWindow $0 "${MainWindowClass}" 1421 FindWindow $1 "${DialogWindowClass}" 1422 ${If} $0 <> 0 1423 ${OrIf} $1 <> 0 1424 WebBrowser::CancelTimer $TimerHandle 1425 StrCpy $ProgressCompleted "${PROGRESS_BAR_APP_LAUNCH_END_STEP}" 1426 Call SetProgressBars 1427 Call SendPing 1428 Return 1429 ${EndIf} 1430 1431 IntOp $AppLaunchWaitTickCount $AppLaunchWaitTickCount + 1 1432 IntOp $0 $AppLaunchWaitTickCount * ${AppLaunchWaitIntervalMS} 1433 ${If} $0 >= ${AppLaunchWaitTimeoutMS} 1434 ; We've waited an unreasonably long time, so just exit. 1435 WebBrowser::CancelTimer $TimerHandle 1436 Call SendPing 1437 Return 1438 ${EndIf} 1439 1440 ${If} $ProgressCompleted < ${PROGRESS_BAR_APP_LAUNCH_END_STEP} 1441 IntOp $ProgressCompleted $ProgressCompleted + 1 1442 Call SetProgressBars 1443 ${EndIf} 1444FunctionEnd 1445 1446Function DisplayDownloadError 1447 WebBrowser::CancelTimer $TimerHandle 1448 ; To better display the error state on the taskbar set the progress completed 1449 ; value to the total value. 1450 ${ITBL3SetProgressValue} "100" "100" 1451 ${ITBL3SetProgressState} "${TBPF_ERROR}" 1452 1453 MessageBox MB_OKCANCEL|MB_ICONSTOP "$(ERROR_DOWNLOAD_CONT)" IDCANCEL +2 IDOK +1 1454 Call LaunchHelpPage 1455 Call SendPing 1456FunctionEnd 1457 1458Function LaunchHelpPage 1459 StrCpy $OpenedDownloadPage "1" ; Already initialized to 0 1460 ClearErrors 1461 ${GetParameters} $0 1462 ${GetOptions} "$0" "/UAC:" $1 1463 ${If} ${Errors} 1464 Call OpenManualDownloadURL 1465 ${Else} 1466 GetFunctionAddress $0 OpenManualDownloadURL 1467 UAC::ExecCodeSegment $0 1468 ${EndIf} 1469FunctionEnd 1470 1471Function OpenManualDownloadURL 1472 ClearErrors 1473 ReadINIStr $0 "${PARTNER_INI}" "DownloadURL" "FallbackPage" 1474 ${IfNot} ${Errors} 1475 ExecShell "open" "$0" 1476 ${Else} 1477 ExecShell "open" "${URLManualDownload}${URLManualDownloadAppend}" 1478 ${EndIf} 1479FunctionEnd 1480 1481Function ShouldPromptForProfileCleanup 1482 ; This will be our return value. 1483 StrCpy $ProfileCleanupPromptType 0 1484 1485 ; Only consider installations of the same architecture we're installing. 1486 ${If} $ArchToInstall == ${ARCH_AMD64} 1487 ${OrIf} $ArchToInstall == ${ARCH_AARCH64} 1488 SetRegView 64 1489 ${Else} 1490 SetRegView 32 1491 ${EndIf} 1492 1493 ; Make sure $APPDATA is the user's AppData and not ProgramData. 1494 ; We'll set this back to all at the end of the function. 1495 SetShellVarContext current 1496 1497 ${FindInstallSpecificProfile} 1498 Pop $R0 1499 1500 ${If} $R0 == "" 1501 ; We don't have an install-specific profile, so look for an old-style 1502 ; default profile instead by checking each numbered Profile section. 1503 StrCpy $0 0 1504 ${Do} 1505 ClearErrors 1506 ; Check if the section exists by reading a value that must be present. 1507 ReadINIStr $1 "$APPDATA\Mozilla\Firefox\profiles.ini" "Profile$0" "Path" 1508 ${If} ${Errors} 1509 ; We've run out of profile sections. 1510 ${Break} 1511 ${EndIf} 1512 1513 ClearErrors 1514 ReadINIStr $1 "$APPDATA\Mozilla\Firefox\profiles.ini" "Profile$0" "Default" 1515 ${IfNot} ${Errors} 1516 ${AndIf} $1 == "1" 1517 ; We've found the default profile 1518 ReadINIStr $1 "$APPDATA\Mozilla\Firefox\profiles.ini" "Profile$0" "Path" 1519 ReadINIStr $2 "$APPDATA\Mozilla\Firefox\profiles.ini" "Profile$0" "IsRelative" 1520 ${If} $2 == "1" 1521 StrCpy $R0 "$APPDATA\Mozilla\Firefox\$1" 1522 ${Else} 1523 StrCpy $R0 "$1" 1524 ${EndIf} 1525 ${Break} 1526 ${EndIf} 1527 1528 IntOp $0 $0 + 1 1529 ${Loop} 1530 ${EndIf} 1531 1532 GetFullPathName $R0 $R0 1533 1534 ${If} $R0 == "" 1535 ; No profile to clean up, so don't show the cleanup prompt. 1536 GoTo end 1537 ${EndIf} 1538 1539 ; We have at least one profile present. If we don't have any installations, 1540 ; then we need to show the re-install prompt. We'll say there's an 1541 ; installation present if HKCR\FirefoxURL* exists and points to a real path. 1542 StrCpy $0 0 1543 StrCpy $R9 "" 1544 ${Do} 1545 ClearErrors 1546 EnumRegKey $1 HKCR "" $0 1547 ${If} ${Errors} 1548 ${OrIf} $1 == "" 1549 ${Break} 1550 ${EndIf} 1551 ${WordFind} "$1" "-" "+1{" $2 1552 ${If} $2 == "FirefoxURL" 1553 ClearErrors 1554 ReadRegStr $2 HKCR "$1\DefaultIcon" "" 1555 ${IfNot} ${Errors} 1556 ${GetPathFromString} $2 $1 1557 ${If} ${FileExists} $1 1558 StrCpy $R9 $1 1559 ${Break} 1560 ${EndIf} 1561 ${EndIf} 1562 ${EndIf} 1563 IntOp $0 $0 + 1 1564 ${Loop} 1565 ${If} $R9 == "" 1566 StrCpy $ProfileCleanupPromptType 1 1567 GoTo end 1568 ${EndIf} 1569 1570 ; Okay, there's at least one install, let's see if it's for this channel. 1571 SetShellVarContext all 1572 ${GetSingleInstallPath} "Software\Mozilla\${BrandFullNameInternal}" $0 1573 ${If} $0 == "false" 1574 SetShellVarContext current 1575 ${GetSingleInstallPath} "Software\Mozilla\${BrandFullNameInternal}" $0 1576 ${If} $0 == "false" 1577 ; Existing installs are not for this channel. Don't show any prompt. 1578 GoTo end 1579 ${EndIf} 1580 ${EndIf} 1581 1582 ; Find out what version the default profile was last used on. 1583 ${If} ${FileExists} "$R0\compatibility.ini" 1584 ClearErrors 1585 ReadINIStr $0 "$R0\compatibility.ini" "Compatibility" "LastVersion" 1586 ${If} ${Errors} 1587 GoTo end 1588 ${EndIf} 1589 ${WordFind} $0 "." "+1{" $0 1590 1591 ; We don't know what version we're about to install because we haven't 1592 ; downloaded it yet. Find out what the latest version released on this 1593 ; channel is and assume we'll be installing that one. 1594 Call GetLatestReleasedVersion 1595 ${If} ${Errors} 1596 ; Use this stub installer's version as a fallback when we can't get the 1597 ; real current version; this may be behind, but it's better than nothing. 1598 StrCpy $1 ${AppVersion} 1599 ${EndIf} 1600 1601 ${WordFind} $1 "." "+1{" $1 1602 IntOp $1 $1 - 2 1603 1604 ${If} $1 > $0 1605 ; Default profile was last used more than two versions ago, so we need 1606 ; to show the paveover version of the profile cleanup prompt. 1607 StrCpy $ProfileCleanupPromptType 2 1608 ${EndIf} 1609 ${EndIf} 1610 1611 end: 1612 SetRegView lastused 1613 SetShellVarContext all 1614FunctionEnd 1615 1616Function GetLatestReleasedVersion 1617 ClearErrors 1618 Push $0 ; InetBgDl::GetStats uses $0 for the HTTP error code 1619 ; $1 is our return value, so don't save it 1620 Push $2 ; InetBgDl::GetStats uses $2 to tell us when the transfer is done 1621 Push $3 ; $3 - $5 are also set by InetBgDl::GetStats, but we don't use them 1622 Push $4 1623 Push $5 1624 Push $6 ; This is our response timeout counter 1625 1626 InetBgDL::Get /RESET /END 1627 InetBgDL::Get "https://product-details.mozilla.org/1.0/firefox_versions.json" \ 1628 "$PLUGINSDIR\firefox_versions.json" \ 1629 /CONNECTTIMEOUT 120 /RECEIVETIMEOUT 120 /END 1630 1631 ; Wait for the response, but only give it half a second since this is on the 1632 ; installer startup path (we haven't even shown a window yet). 1633 StrCpy $6 0 1634 ${Do} 1635 Sleep 100 1636 InetBgDL::GetStats 1637 IntOp $6 $6 + 1 1638 1639 ${If} $2 == 0 1640 ${Break} 1641 ${ElseIf} $6 >= 5 1642 InetBgDL::Get /RESET /END 1643 SetErrors 1644 GoTo end 1645 ${EndIf} 1646 ${Loop} 1647 1648 StrCpy $1 0 1649 nsJSON::Set /file "$PLUGINSDIR\firefox_versions.json" 1650 IfErrors end 1651 ${Select} ${Channel} 1652 ${Case} "unofficial" 1653 StrCpy $1 "FIREFOX_NIGHTLY" 1654 ${Case} "nightly" 1655 StrCpy $1 "FIREFOX_NIGHTLY" 1656 ${Case} "aurora" 1657 StrCpy $1 "FIREFOX_DEVEDITION" 1658 ${Case} "beta" 1659 StrCpy $1 "LATEST_FIREFOX_RELEASED_DEVEL_VERSION" 1660 ${Case} "release" 1661 StrCpy $1 "LATEST_FIREFOX_VERSION" 1662 ${EndSelect} 1663 nsJSON::Get $1 /end 1664 1665 end: 1666 ${If} ${Errors} 1667 ${OrIf} $1 == 0 1668 SetErrors 1669 StrCpy $1 0 1670 ${Else} 1671 Pop $1 1672 ${EndIf} 1673 1674 Pop $6 1675 Pop $5 1676 Pop $4 1677 Pop $3 1678 Pop $2 1679 Pop $0 1680FunctionEnd 1681 1682; Determine which architecture build we should download and install. 1683; AArch64 is always selected if it's the native architecture of the machine. 1684; Otherwise, we check a few things to determine if AMD64 is appropriate: 1685; 1) Running a 64-bit OS (we've already checked the OS version). 1686; 2) An amount of RAM strictly greater than RAM_NEEDED_FOR_64BIT 1687; 3) No third-party products installed that cause issues with the 64-bit build. 1688; Currently this includes Lenovo OneKey Theater and Lenovo Energy Management. 1689; We also make sure that the partner.ini file contains a download URL for the 1690; selected architecture, when a partner.ini file eixsts. 1691; If any of those checks fail, the 32-bit x86 build is selected. 1692Function GetArchToInstall 1693 StrCpy $ArchToInstall ${ARCH_X86} 1694 1695 ${If} ${IsNativeARM64} 1696 StrCpy $ArchToInstall ${ARCH_AARCH64} 1697 GoTo downloadUrlCheck 1698 ${EndIf} 1699 1700 ${IfNot} ${IsNativeAMD64} 1701 Return 1702 ${EndIf} 1703 1704 System::Call "*(i 64, i, l 0, l, l, l, l, l, l)p.r1" 1705 System::Call "Kernel32::GlobalMemoryStatusEx(p r1)" 1706 System::Call "*$1(i, i, l.r2, l, l, l, l, l, l)" 1707 System::Free $1 1708 ${If} $2 L<= ${RAM_NEEDED_FOR_64BIT} 1709 Return 1710 ${EndIf} 1711 1712 ; Lenovo OneKey Theater can theoretically be in a directory other than this 1713 ; one, because some installer versions let you change it, but it's unlikely. 1714 ${If} ${FileExists} "$PROGRAMFILES32\Lenovo\Onekey Theater\windowsapihookdll64.dll" 1715 Return 1716 ${EndIf} 1717 1718 ${If} ${FileExists} "$PROGRAMFILES32\Lenovo\Energy Management\Energy Management.exe" 1719 Return 1720 ${EndIf} 1721 1722 StrCpy $ArchToInstall ${ARCH_AMD64} 1723 1724 downloadUrlCheck: 1725 ; If we've selected an architecture that doesn't have a download URL in the 1726 ; partner.ini, but there is a URL there for 32-bit x86, then fall back to 1727 ; 32-bit x86 on the theory that we should never use a non-partner build if 1728 ; we are configured as a partner installer, even if the only build that's 1729 ; provided is suboptimal for the machine. If there isn't even an x86 URL, 1730 ; then we won't force x86 and GetDownloadURL will stick with the built-in URL. 1731 ClearErrors 1732 ReadINIStr $1 "${PARTNER_INI}" "DownloadURL" "X86" 1733 ${IfNot} ${Errors} 1734 ${If} $ArchToInstall == ${ARCH_AMD64} 1735 ReadINIStr $1 "${PARTNER_INI}" "DownloadURL" "AMD64" 1736 ${If} ${Errors} 1737 StrCpy $ArchToInstall ${ARCH_X86} 1738 ${EndIf} 1739 ${ElseIf} $ArchToInstall == ${ARCH_AARCH64} 1740 ReadINIStr $1 "${PARTNER_INI}" "DownloadURL" "AArch64" 1741 ${If} ${Errors} 1742 StrCpy $ArchToInstall ${ARCH_X86} 1743 ${EndIf} 1744 ${EndIf} 1745 ${EndIf} 1746FunctionEnd 1747 1748Function GetDownloadURL 1749 Push $0 1750 Push $1 1751 1752 ; Start with the appropriate URL from our built-in branding info. 1753 ${If} $ArchToInstall == ${ARCH_AMD64} 1754 StrCpy $0 "${URLStubDownloadAMD64}${URLStubDownloadAppend}" 1755 ${ElseIf} $ArchToInstall == ${ARCH_AARCH64} 1756 StrCpy $0 "${URLStubDownloadAArch64}${URLStubDownloadAppend}" 1757 ${Else} 1758 StrCpy $0 "${URLStubDownloadX86}${URLStubDownloadAppend}" 1759 ${EndIf} 1760 1761 ; If we have a partner.ini file then use the URL from there instead. 1762 ClearErrors 1763 ${If} $ArchToInstall == ${ARCH_AMD64} 1764 ReadINIStr $1 "${PARTNER_INI}" "DownloadURL" "AMD64" 1765 ${ElseIf} $ArchToInstall == ${ARCH_AARCH64} 1766 ReadINIStr $1 "${PARTNER_INI}" "DownloadURL" "AArch64" 1767 ${Else} 1768 ReadINIStr $1 "${PARTNER_INI}" "DownloadURL" "X86" 1769 ${EndIf} 1770 ${IfNot} ${Errors} 1771 StrCpy $0 "$1" 1772 ${EndIf} 1773 1774 Pop $1 1775 Exch $0 1776FunctionEnd 1777 1778Section 1779SectionEnd 1780