Source code

Revision control

Other Tools

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
15
SetDatablockOptimize on
16
SetCompress off
17
CRCCheck on
18
19
RequestExecutionLevel user
20
21
Unicode true
22
ManifestSupportedOS all
23
ManifestDPIAware true
24
25
!addplugindir ./
26
27
Var Dialog
28
Var Progressbar
29
Var ProgressbarMarqueeIntervalMS
30
Var CheckboxSetAsDefault
31
Var CheckboxShortcuts
32
Var CheckboxSendPing
33
Var CheckboxInstallMaintSvc
34
Var LabelBlurb
35
Var BgBitmapImage
36
Var HwndBgBitmapControl
37
Var CurrentBlurbIdx
38
Var CheckboxCleanupProfile
39
40
Var FontFamilyName
41
Var FontInstalling
42
Var FontHeader
43
Var FontBlurb
44
Var FontFooter
45
Var FontButton
46
Var FontCheckbox
47
48
Var CanWriteToInstallDir
49
Var HasRequiredSpaceAvailable
50
Var IsDownloadFinished
51
Var DownloadSizeBytes
52
Var DownloadReset
53
Var ExistingTopDir
54
Var SpaceAvailableBytes
55
Var InitialInstallDir
56
Var HandleDownload
57
Var CanSetAsDefault
58
Var InstallCounterStep
59
Var InstallTotalSteps
60
Var ProgressCompleted
61
Var UsingHighContrastMode
62
63
Var ExitCode
64
Var FirefoxLaunchCode
65
66
Var StartDownloadPhaseTickCount
67
; Since the Intro and Options pages can be displayed multiple times the total
68
; seconds spent on each of these pages is reported.
69
Var IntroPhaseSeconds
70
Var OptionsPhaseSeconds
71
; The tick count for the last download.
72
Var StartLastDownloadTickCount
73
; The number of seconds from the start of the download phase until the first
74
; bytes are received. This is only recorded for first request so it is possible
75
; to determine connection issues for the first request.
76
Var DownloadFirstTransferSeconds
77
; The last four tick counts are for the end of a phase in the installation page.
78
Var EndDownloadPhaseTickCount
79
Var EndPreInstallPhaseTickCount
80
Var EndInstallPhaseTickCount
81
Var EndFinishPhaseTickCount
82
83
Var InitialInstallRequirementsCode
84
Var ExistingProfile
85
Var ExistingVersion
86
Var ExistingBuildID
87
Var DownloadedBytes
88
Var DownloadRetryCount
89
Var OpenedDownloadPage
90
Var DownloadServerIP
91
Var PostSigningData
92
Var PreviousInstallDir
93
Var ProfileCleanupPromptType
94
Var ProfileCleanupHeaderString
95
Var ProfileCleanupButtonString
96
Var AppLaunchWaitTickCount
97
98
!define ARCH_X86 1
99
!define ARCH_AMD64 2
100
!define ARCH_AARCH64 3
101
Var ArchToInstall
102
103
; Uncomment the following to prevent pinging the metrics server when testing
104
; the stub installer
105
;!define STUB_DEBUG
106
107
!define StubURLVersion "v8"
108
109
; Successful install exit code
110
!define ERR_SUCCESS 0
111
112
/**
113
* The following errors prefixed with ERR_DOWNLOAD apply to the download phase.
114
*/
115
; The download was cancelled by the user
116
!define ERR_DOWNLOAD_CANCEL 10
117
118
; Too many attempts to download. The maximum attempts is defined in
119
; DownloadMaxRetries.
120
!define ERR_DOWNLOAD_TOO_MANY_RETRIES 11
121
122
/**
123
* The following errors prefixed with ERR_PREINSTALL apply to the pre-install
124
* check phase.
125
*/
126
; Unable to acquire a file handle to the downloaded file
127
!define ERR_PREINSTALL_INVALID_HANDLE 20
128
129
; The downloaded file's certificate is not trusted by the certificate store.
130
!define ERR_PREINSTALL_CERT_UNTRUSTED 21
131
132
; The downloaded file's certificate attribute values were incorrect.
133
!define ERR_PREINSTALL_CERT_ATTRIBUTES 22
134
135
; The downloaded file's certificate is not trusted by the certificate store and
136
; certificate attribute values were incorrect.
137
!define ERR_PREINSTALL_CERT_UNTRUSTED_AND_ATTRIBUTES 23
138
139
; Timed out while waiting for the certificate checks to run.
140
!define ERR_PREINSTALL_CERT_TIMEOUT 24
141
142
/**
143
* The following errors prefixed with ERR_INSTALL apply to the install phase.
144
*/
145
; The installation timed out. The installation timeout is defined by the number
146
; of progress steps defined in InstallTotalSteps and the install timer
147
; interval defined in InstallIntervalMS
148
!define ERR_INSTALL_TIMEOUT 30
149
150
; Maximum times to retry the download before displaying an error
151
!define DownloadMaxRetries 9
152
153
; Minimum size expected to download in bytes
154
!define DownloadMinSizeBytes 15728640 ; 15 MB
155
156
; Maximum size expected to download in bytes
157
!define DownloadMaxSizeBytes 157286400 ; 150 MB
158
159
; Interval before retrying to download. 3 seconds is used along with 10
160
; attempted downloads (the first attempt along with 9 retries) to give a
161
; minimum of 30 seconds or retrying before giving up.
162
!define DownloadRetryIntervalMS 3000
163
164
; Interval for the download timer
165
!define DownloadIntervalMS 200
166
167
; Timeout for the certificate check
168
!define PreinstallCertCheckMaxWaitSec 30
169
170
; Interval for the install timer
171
!define InstallIntervalMS 100
172
173
; Number of steps for the install progress.
174
; This might not be enough when installing on a slow network drive so it will
175
; fallback to downloading the full installer if it reaches this number.
176
177
; Approximately 150 seconds with a 100 millisecond timer.
178
!define InstallCleanTotalSteps 1500
179
180
; Approximately 165 seconds with a 100 millisecond timer.
181
!define InstallPaveOverTotalSteps 1650
182
183
; Blurb duty cycle
184
!define BlurbDisplayMS 19500
185
!define BlurbBlankMS 500
186
187
; Interval between checks for the application window and progress bar updates.
188
!define AppLaunchWaitIntervalMS 100
189
190
; Total time to wait for the application to start before just exiting.
191
!define AppLaunchWaitTimeoutMS 10000
192
193
; Maximum value of the download/install/launch progress bar, and the end values
194
; for each individual stage.
195
!define PROGRESS_BAR_TOTAL_STEPS 500
196
!define PROGRESS_BAR_DOWNLOAD_END_STEP 300
197
!define PROGRESS_BAR_INSTALL_END_STEP 475
198
!define PROGRESS_BAR_APP_LAUNCH_END_STEP 500
199
200
; Amount of physical memory required for the 64-bit build to be selected (2 GB).
201
; Machines with this or less RAM get the 32-bit build, even with a 64-bit OS.
202
!define RAM_NEEDED_FOR_64BIT 0x80000000
203
204
; Attempt to elevate Standard Users in addition to users that
205
; are a member of the Administrators group.
206
!define NONADMIN_ELEVATE
207
208
!define CONFIG_INI "config.ini"
209
!define PARTNER_INI "$EXEDIR\partner.ini"
210
211
!ifndef FILE_SHARE_READ
212
!define FILE_SHARE_READ 1
213
!endif
214
!ifndef GENERIC_READ
215
!define GENERIC_READ 0x80000000
216
!endif
217
!ifndef OPEN_EXISTING
218
!define OPEN_EXISTING 3
219
!endif
220
!ifndef INVALID_HANDLE_VALUE
221
!define INVALID_HANDLE_VALUE -1
222
!endif
223
224
!define DefaultInstDir32bit "$PROGRAMFILES32\${BrandFullName}"
225
!define DefaultInstDir64bit "$PROGRAMFILES64\${BrandFullName}"
226
227
!include "nsDialogs.nsh"
228
!include "LogicLib.nsh"
229
!include "FileFunc.nsh"
230
!include "TextFunc.nsh"
231
!include "WinVer.nsh"
232
!include "WordFunc.nsh"
233
234
!insertmacro GetParameters
235
!insertmacro GetOptions
236
!insertmacro LineFind
237
!insertmacro StrFilter
238
239
!include "locales.nsi"
240
!include "branding.nsi"
241
242
!include "defines.nsi"
243
244
; Must be included after defines.nsi
245
!include "locale-fonts.nsh"
246
247
; The OFFICIAL define is a workaround to support different urls for Release and
248
; Beta since they share the same branding when building with other branches that
249
; set the update channel to beta.
250
!ifdef OFFICIAL
251
!ifdef BETA_UPDATE_CHANNEL
252
!undef URLStubDownloadX86
253
!undef URLStubDownloadAMD64
254
!undef URLStubDownloadAArch64
258
!undef URLManualDownload
260
!undef Channel
261
!define Channel "beta"
262
!endif
263
!endif
264
265
!include "common.nsh"
266
267
!insertmacro ElevateUAC
268
!insertmacro GetLongPath
269
!insertmacro GetPathFromString
270
!insertmacro GetParent
271
!insertmacro GetSingleInstallPath
272
!insertmacro GetTextWidthHeight
273
!insertmacro InitHashAppModelId
274
!insertmacro IsUserAdmin
275
!insertmacro RemovePrecompleteEntries
276
!insertmacro SetBrandNameVars
277
!insertmacro ITBL3Create
278
!insertmacro UnloadUAC
279
280
VIAddVersionKey "FileDescription" "${BrandShortName} Installer"
281
VIAddVersionKey "OriginalFilename" "setup-stub.exe"
282
283
Name "$BrandFullName"
284
OutFile "setup-stub.exe"
285
Icon "firefox64.ico"
286
XPStyle on
287
BrandingText " "
288
ChangeUI all "nsisui.exe"
289
290
!ifdef ${AB_CD}_rtl
291
LoadLanguageFile "locale-rtl.nlf"
292
!else
293
LoadLanguageFile "locale.nlf"
294
!endif
295
296
!include "nsisstrings.nlf"
297
298
Caption "$(INSTALLER_WIN_CAPTION)"
299
300
Page custom createProfileCleanup
301
Page custom createInstall ; Download / Installation page
302
303
Function .onInit
304
; Remove the current exe directory from the search order.
305
; This only effects LoadLibrary calls and not implicitly loaded DLLs.
306
System::Call 'kernel32::SetDllDirectoryW(w "")'
307
308
StrCpy $LANGUAGE 0
309
; This macro is used to set the brand name variables but the ini file method
310
; isn't supported for the stub installer.
311
${SetBrandNameVars} "$PLUGINSDIR\ignored.ini"
312
313
; Don't install on systems that don't support SSE2. The parameter value of
314
; 10 is for PF_XMMI64_INSTRUCTIONS_AVAILABLE which will check whether the
315
; SSE2 instruction set is available.
316
System::Call "kernel32::IsProcessorFeaturePresent(i 10)i .R7"
317
318
; Windows NT 6.0 (Vista/Server 2008) and lower are not supported.
319
${Unless} ${AtLeastWin7}
320
${If} "$R7" == "0"
321
strCpy $R7 "$(WARN_MIN_SUPPORTED_OSVER_CPU_MSG)"
322
${Else}
323
strCpy $R7 "$(WARN_MIN_SUPPORTED_OSVER_MSG)"
324
${EndIf}
325
MessageBox MB_OKCANCEL|MB_ICONSTOP "$R7" IDCANCEL +2
326
ExecShell "open" "${URLSystemRequirements}"
327
Quit
328
${EndUnless}
329
330
; SSE2 CPU support
331
${If} "$R7" == "0"
332
MessageBox MB_OKCANCEL|MB_ICONSTOP "$(WARN_MIN_SUPPORTED_CPU_MSG)" IDCANCEL +2
333
ExecShell "open" "${URLSystemRequirements}"
334
Quit
335
${EndIf}
336
337
Call GetArchToInstall
338
${If} $ArchToInstall == ${ARCH_AARCH64}
339
${OrIf} $ArchToInstall == ${ARCH_AMD64}
340
StrCpy $INSTDIR "${DefaultInstDir64bit}"
341
${Else}
342
StrCpy $INSTDIR "${DefaultInstDir32bit}"
343
${EndIf}
344
345
; Require elevation if the user can elevate
346
${ElevateUAC}
347
348
; If we have any existing installation, use its location as the default
349
; path for this install, even if it's not the same architecture.
350
SetRegView 32
351
SetShellVarContext all ; Set SHCTX to HKLM
352
${GetSingleInstallPath} "Software\Mozilla\${BrandFullNameInternal}" $R9
353
354
${If} "$R9" == "false"
355
${If} ${IsNativeAMD64}
356
${OrIf} ${IsNativeARM64}
357
SetRegView 64
358
${GetSingleInstallPath} "Software\Mozilla\${BrandFullNameInternal}" $R9
359
${EndIf}
360
${EndIf}
361
362
${If} "$R9" == "false"
363
SetShellVarContext current ; Set SHCTX to HKCU
364
${GetSingleInstallPath} "Software\Mozilla\${BrandFullNameInternal}" $R9
365
${EndIf}
366
367
StrCpy $PreviousInstallDir ""
368
${If} "$R9" != "false"
369
StrCpy $PreviousInstallDir "$R9"
370
StrCpy $INSTDIR "$PreviousInstallDir"
371
${EndIf}
372
373
; Used to determine if the default installation directory was used.
374
StrCpy $InitialInstallDir "$INSTDIR"
375
376
ClearErrors
377
WriteRegStr HKLM "Software\Mozilla" "${BrandShortName}InstallerTest" \
378
"Write Test"
379
380
; Only display set as default when there is write access to HKLM and on Win7
381
; and below.
382
${If} ${Errors}
383
${OrIf} ${AtLeastWin8}
384
StrCpy $CanSetAsDefault "false"
385
${Else}
386
DeleteRegValue HKLM "Software\Mozilla" "${BrandShortName}InstallerTest"
387
StrCpy $CanSetAsDefault "true"
388
${EndIf}
389
StrCpy $CheckboxSetAsDefault "0"
390
391
; The interval in MS used for the progress bars set as marquee.
392
StrCpy $ProgressbarMarqueeIntervalMS "10"
393
394
; Initialize the majority of variables except those that need to be reset
395
; when a page is displayed.
396
StrCpy $ExitCode "${ERR_DOWNLOAD_CANCEL}"
397
StrCpy $IntroPhaseSeconds "0"
398
StrCpy $OptionsPhaseSeconds "0"
399
StrCpy $EndPreInstallPhaseTickCount "0"
400
StrCpy $EndInstallPhaseTickCount "0"
401
StrCpy $StartDownloadPhaseTickCount "0"
402
StrCpy $EndDownloadPhaseTickCount "0"
403
StrCpy $InitialInstallRequirementsCode ""
404
StrCpy $IsDownloadFinished ""
405
StrCpy $FirefoxLaunchCode "0"
406
StrCpy $CheckboxShortcuts "1"
407
StrCpy $CheckboxSendPing "1"
408
StrCpy $CheckboxCleanupProfile "0"
409
!ifdef MOZ_MAINTENANCE_SERVICE
410
; We can only install the maintenance service if the user is an admin.
411
Call IsUserAdmin
412
Pop $0
413
${If} "$0" == "true"
414
StrCpy $CheckboxInstallMaintSvc "1"
415
${Else}
416
StrCpy $CheckboxInstallMaintSvc "0"
417
${EndIf}
418
!else
419
StrCpy $CheckboxInstallMaintSvc "0"
420
!endif
421
422
StrCpy $FontFamilyName ""
423
!ifdef FONT_FILE1
424
${If} ${FileExists} "$FONTS\${FONT_FILE1}"
425
StrCpy $FontFamilyName "${FONT_NAME1}"
426
${EndIf}
427
!endif
428
429
!ifdef FONT_FILE2
430
${If} $FontFamilyName == ""
431
${AndIf} ${FileExists} "$FONTS\${FONT_FILE2}"
432
StrCpy $FontFamilyName "${FONT_NAME2}"
433
${EndIf}
434
!endif
435
436
${If} $FontFamilyName == ""
437
StrCpy $FontFamilyName "$(^Font)"
438
${EndIf}
439
440
CreateFont $FontHeader "$FontFamilyName" "${INSTALL_HEADER_FONT_SIZE}" \
441
"${INSTALL_HEADER_FONT_WEIGHT}"
442
CreateFont $FontInstalling "$FontFamilyName" "${INSTALL_INSTALLING_FONT_SIZE}" \
443
"${INSTALL_INSTALLING_FONT_WEIGHT}"
444
CreateFont $FontButton "$FontFamilyName" "10" "500"
445
CreateFont $FontBlurb "$FontFamilyName" "15" "400"
446
CreateFont $FontFooter "$FontFamilyName" "13" "400"
447
CreateFont $FontCheckbox "$FontFamilyName" "10" "400"
448
449
InitPluginsDir
450
File /oname=$PLUGINSDIR\bgstub.jpg "bgstub.jpg"
451
File /oname=$PLUGINSDIR\bgstub_2x.jpg "bgstub_2x.jpg"
452
453
; Detect whether the machine is running with a high contrast theme.
454
; We'll hide our background images in that case, both because they don't
455
; always render properly and also to improve the contrast.
456
System::Call '*(i 12, i 0, p 0) p . r0'
457
; 0x42 == SPI_GETHIGHCONTRAST
458
System::Call 'user32::SystemParametersInfoW(i 0x42, i 0, p r0, i 0)'
459
System::Call '*$0(i, i . r1, p)'
460
System::Free $0
461
IntOp $UsingHighContrastMode $1 & 1
462
463
SetShellVarContext all ; Set SHCTX to All Users
464
; If the user doesn't have write access to the installation directory set
465
; the installation directory to a subdirectory of the All Users application
466
; directory and if the user can't write to that location set the installation
467
; directory to a subdirectory of the users local application directory
468
; (e.g. non-roaming).
469
Call CanWrite
470
${If} "$CanWriteToInstallDir" == "false"
471
StrCpy $INSTDIR "$APPDATA\${BrandFullName}\"
472
Call CanWrite
473
${If} "$CanWriteToInstallDir" == "false"
474
; This should never happen but just in case.
475
StrCpy $CanWriteToInstallDir "false"
476
${Else}
477
StrCpy $INSTDIR "$LOCALAPPDATA\${BrandFullName}\"
478
Call CanWrite
479
${EndIf}
480
${EndIf}
481
482
Call CheckSpace
483
484
${If} ${FileExists} "$INSTDIR"
485
; Always display the long path if the path exists.
486
${GetLongPath} "$INSTDIR" $INSTDIR
487
${EndIf}
488
489
; Check whether the install requirements are satisfied using the default
490
; values for metrics.
491
${If} "$InitialInstallRequirementsCode" == ""
492
${If} "$CanWriteToInstallDir" != "true"
493
${AndIf} "$HasRequiredSpaceAvailable" != "true"
494
StrCpy $InitialInstallRequirementsCode "1"
495
${ElseIf} "$CanWriteToInstallDir" != "true"
496
StrCpy $InitialInstallRequirementsCode "2"
497
${ElseIf} "$HasRequiredSpaceAvailable" != "true"
498
StrCpy $InitialInstallRequirementsCode "3"
499
${Else}
500
StrCpy $InitialInstallRequirementsCode "0"
501
${EndIf}
502
${EndIf}
503
504
Call CanWrite
505
${If} "$CanWriteToInstallDir" == "false"
506
MessageBox MB_OK|MB_ICONEXCLAMATION "$(WARN_WRITE_ACCESS_QUIT)$\n$\n$INSTDIR"
507
Quit
508
${EndIf}
509
510
Call CheckSpace
511
${If} "$HasRequiredSpaceAvailable" == "false"
512
MessageBox MB_OK|MB_ICONEXCLAMATION "$(WARN_DISK_SPACE_QUIT)"
513
Quit
514
${EndIf}
515
516
${InitHashAppModelId} "$INSTDIR" "Software\Mozilla\${AppName}\TaskBarIDs"
517
FunctionEnd
518
519
; .onGUIInit isn't needed except for RTL locales
520
!ifdef ${AB_CD}_rtl
521
Function .onGUIInit
522
; Since NSIS RTL support doesn't mirror progress bars use Windows mirroring.
523
${NSD_AddExStyle} $HWNDPARENT ${WS_EX_LAYOUTRTL}
524
${RemoveExStyle} $HWNDPARENT ${WS_EX_RTLREADING}
525
${RemoveExStyle} $HWNDPARENT ${WS_EX_RIGHT}
526
${NSD_AddExStyle} $HWNDPARENT ${WS_EX_LEFT}|${WS_EX_LTRREADING}
527
FunctionEnd
528
!endif
529
530
Function .onGUIEnd
531
Delete "$PLUGINSDIR\_temp"
532
Delete "$PLUGINSDIR\download.exe"
533
Delete "$PLUGINSDIR\${CONFIG_INI}"
534
535
${UnloadUAC}
536
FunctionEnd
537
538
Function .onUserAbort
539
${NSD_KillTimer} StartDownload
540
${NSD_KillTimer} OnDownload
541
${NSD_KillTimer} CheckInstall
542
${NSD_KillTimer} FinishInstall
543
${NSD_KillTimer} DisplayDownloadError
544
${NSD_KillTimer} NextBlurb
545
${NSD_KillTimer} ClearBlurb
546
547
${If} "$IsDownloadFinished" != ""
548
; Go ahead and cancel the download so it doesn't keep running while this
549
; prompt is up. We'll resume it if the user decides to continue.
550
InetBgDL::Get /RESET /END
551
552
${ShowTaskDialog} $(STUB_CANCEL_PROMPT_HEADING) \
553
$(STUB_CANCEL_PROMPT_MESSAGE) \
554
$(STUB_CANCEL_PROMPT_BUTTON_CONTINUE) \
555
$(STUB_CANCEL_PROMPT_BUTTON_EXIT)
556
Pop $0
557
${If} $0 == 1002
558
; The cancel button was clicked
559
Call LaunchHelpPage
560
Call SendPing
561
${Else}
562
; Either the continue button was clicked or the dialog was dismissed
563
Call StartDownload
564
${EndIf}
565
${Else}
566
Call SendPing
567
${EndIf}
568
569
; Aborting the abort will allow SendPing to hide the installer window and
570
; close the installer after it sends the metrics ping, or allow us to just go
571
; back to installing if that's what the user selected.
572
Abort
573
FunctionEnd
574
575
Function DrawBackgroundImage
576
${NSD_CreateBitmap} 0 0 100% 100% ""
577
Pop $HwndBgBitmapControl
578
579
; If the scaling factor is 100%, use the 1x image; the 2x images scaled down
580
; by that much don't always look good because some of them use thinner lines
581
; and a darker background (over which aliasing is more visible).
582
System::Call 'user32::GetWindowDC(i $HWNDPARENT) i .r0'
583
System::Call 'gdi32::GetDeviceCaps(i $0, i 88) i .r1' ; 88 = LOGPIXELSX
584
System::Call 'user32::ReleaseDC(i $HWNDPARENT, i $0)'
585
${If} $1 <= 96
586
${SetStretchedImageOLE} $HwndBgBitmapControl $PLUGINSDIR\bgstub.jpg $BgBitmapImage
587
${Else}
588
${SetStretchedImageOLE} $HwndBgBitmapControl $PLUGINSDIR\bgstub_2x.jpg $BgBitmapImage
589
${EndIf}
590
591
; transparent bg on control prevents flicker on redraw
592
SetCtlColors $HwndBgBitmapControl ${COMMON_TEXT_COLOR} transparent
593
FunctionEnd
594
595
Function createProfileCleanup
596
Call ShouldPromptForProfileCleanup
597
${Select} $ProfileCleanupPromptType
598
${Case} 0
599
StrCpy $CheckboxCleanupProfile 0
600
Abort ; Skip this page
601
${Case} 1
602
StrCpy $ProfileCleanupHeaderString $(STUB_CLEANUP_REINSTALL_HEADER2)
603
StrCpy $ProfileCleanupButtonString $(STUB_CLEANUP_REINSTALL_BUTTON)
604
${Case} 2
605
StrCpy $ProfileCleanupHeaderString $(STUB_CLEANUP_PAVEOVER_HEADER2)
606
StrCpy $ProfileCleanupButtonString $(STUB_CLEANUP_PAVEOVER_BUTTON)
607
${EndSelect}
608
609
nsDialogs::Create /NOUNLOAD 1018
610
Pop $Dialog
611
612
SetCtlColors $HWNDPARENT ${COMMON_TEXT_COLOR} ${COMMON_BACKGROUND_COLOR}
613
614
; Since the text color for controls is set in this Dialog the foreground and
615
; background colors of the Dialog must also be hardcoded.
616
SetCtlColors $Dialog ${COMMON_TEXT_COLOR} ${COMMON_BACKGROUND_COLOR}
617
618
FindWindow $7 "#32770" "" $HWNDPARENT
619
${GetDlgItemWidthHeight} $HWNDPARENT $8 $9
620
621
; Resize the Dialog to fill the entire window
622
System::Call 'user32::MoveWindow(i$Dialog,i0,i0,i $8,i $9,i0)'
623
624
GetDlgItem $0 $HWNDPARENT 1 ; Install button
625
ShowWindow $0 ${SW_HIDE}
626
EnableWindow $0 0
627
628
GetDlgItem $0 $HWNDPARENT 3 ; Back button
629
ShowWindow $0 ${SW_HIDE}
630
EnableWindow $0 0
631
632
GetDlgItem $0 $HWNDPARENT 2 ; Cancel button
633
; Hide the Cancel button, but don't disable it (or else it won't be possible
634
; to close the window)
635
ShowWindow $0 ${SW_HIDE}
636
637
GetDlgItem $0 $HWNDPARENT 10 ; Default browser checkbox
638
; Hiding and then disabling allows Esc to still exit the installer
639
ShowWindow $0 ${SW_HIDE}
640
EnableWindow $0 0
641
642
GetDlgItem $0 $HWNDPARENT 11 ; Footer text
643
ShowWindow $0 ${SW_HIDE}
644
EnableWindow $0 0
645
646
; Draw the main prompt header label.
647
!if ${PROFILE_CLEANUP_LABEL_WIDTH} == "100%"
648
${GetDlgItemWidthHeight} $HWNDPARENT $0 $1
649
; Allow for some padding around the dialog edges.
650
IntOp $1 $0 * 90
651
IntOp $1 $1 / 100
652
653
; Center the text in the dialog.
654
IntOp $R1 $1 / 2
655
IntOp $0 $0 / 2
656
IntOp $9 $0 - $R1
657
${GetTextWidthHeight} $ProfileCleanupHeaderString $FontHeader $1 $R1 $R2
658
!else
659
${DialogUnitsToPixels} ${PROFILE_CLEANUP_LABEL_WIDTH} X $1
660
${GetTextWidthHeight} $ProfileCleanupHeaderString $FontHeader $1 $1 $R2
661
${ConvertLeftCoordForRTL} ${PROFILE_CLEANUP_LABEL_LEFT} $1 $9
662
!endif
663
; If this text is over the maximum height, drop the font size until it fits.
664
StrCpy $4 $FontHeader
665
!ifdef PROFILE_CLEANUP_LABEL_HEIGHT
666
${DialogUnitsToPixels} ${PROFILE_CLEANUP_LABEL_HEIGHT} Y $2
667
StrCpy $3 ${INSTALL_HEADER_FONT_SIZE}
668
${While} $R2 > $2
669
IntOp $3 $3 - 2
670
CreateFont $4 "$FontFamilyName" $3 ${INSTALL_HEADER_FONT_WEIGHT}
671
${GetTextWidthHeight} $ProfileCleanupHeaderString $4 $1 $R1 $R2
672
${EndWhile}
673
!endif
674
${NSD_CreateLabel} $9 ${PROFILE_CLEANUP_LABEL_TOP} $1 $R2 \
675
"$ProfileCleanupHeaderString"
676
Pop $0
677
!if ${PROFILE_CLEANUP_LABEL_ALIGN} == "center"
678
${NSD_AddStyle} $0 ${SS_CENTER}
679
!endif
680
SendMessage $0 ${WM_SETFONT} $4 0
681
SetCtlColors $0 ${COMMON_TEXT_COLOR} transparent
682
683
; For the checkbox, first find how much height we're going to need for the
684
; label text.
685
${If} ${PROFILE_CLEANUP_CHECKBOX_WIDTH} == "100%"
686
${GetDlgItemWidthHeight} $HWNDPARENT $R1 $R2
687
${Else}
688
${DialogUnitsToPixels} ${PROFILE_CLEANUP_CHECKBOX_WIDTH} X $R1
689
${EndIf}
690
; Subtract out the width of the checkbox itself and any padding/border so that
691
; PROFILE_CLEANUP_CHECKBOX_WIDTH can be the width of the entire control and
692
; doesn't have to guess. We used a fixed (but DPI-adjusted) 25 pixels to
693
; represent all the things we need to subtract. Using a fixed number of pixels
694
; for this seems dubious, but the obvious method of using SM_CXMENUCHECK
695
; seems to be not quite enough by a pixel or two in certain situations for
696
; mysterious reasons, and this method was taken from what the WinForms
697
; checkbox control does according to the .NET Framework 4.8 reference source.
698
; Get the DPI for the monitor this window is on.
699
System::Call 'user32::GetWindowDC(i $HWNDPARENT) i .R8'
700
System::Call 'gdi32::GetDeviceCaps(i $R8, i 88) i .R9' ; 88 = LOGPIXELSX
701
System::Call 'user32::ReleaseDC(i $HWNDPARENT, i $R8)'
702
; Divide the DPI by 96 to get the scaling factor, and multiply the scaling
703
; factor by 25 (but backwards to avoid truncating the scale factor).
704
IntOp $1 $R9 * 25
705
IntOp $1 $1 / 96
706
; Subtract out the converted 25 pixels from the width available for the text.
707
IntOp $R2 $R1 - $1
708
${GetTextWidthHeight} "$(STUB_CLEANUP_CHECKBOX_LABEL)" $FontCheckbox $R2 \
709
$R3 $R2
710
; Now that we know the size for the checkbox, position it in the dialog.
711
${If} ${PROFILE_CLEANUP_CHECKBOX_LEFT} == "center"
712
${GetDlgItemWidthHeight} $HWNDPARENT $R4 $R5
713
IntOp $R5 $R3 + $1
714
IntOp $R6 $R5 / 2
715
IntOp $R3 $R4 / 2
716
IntOp $R3 $R3 - $R6
717
${Else}
718
StrCpy $R3 ${PROFILE_CLEANUP_CHECKBOX_LEFT}
719
${EndIf}
720
${GetDlgItemBottomPX} $0 $1
721
; Add a bit of margin above the checkbox.
722
${DialogUnitsToPixels} ${PROFILE_CLEANUP_CHECKBOX_TOP_MARGIN} Y $2
723
IntOp $1 $1 + $2
724
ClearErrors
725
${WordFind} "${PROFILE_CLEANUP_CHECKBOX_WIDTH}" "%" "E#" $9
726
${If} ${Errors}
727
${ConvertLeftCoordForRTL} $R3 ${PROFILE_CLEANUP_CHECKBOX_WIDTH} $R3
728
${EndIf}
729
${NSD_CreateCheckbox} $R3 $1 ${PROFILE_CLEANUP_CHECKBOX_WIDTH} $R2 \
730
$(STUB_CLEANUP_CHECKBOX_LABEL)
731
Pop $CheckboxCleanupProfile
732
SendMessage $CheckboxCleanupProfile ${WM_SETFONT} $FontCheckbox 0
733
; The uxtheme must be disabled on checkboxes in order to override the system
734
; colors and have a transparent background.
735
System::Call 'uxtheme::SetWindowTheme(i $CheckboxCleanupProfile, w " ", w " ")'
736
SetCtlColors $CheckboxCleanupProfile ${COMMON_TEXT_COLOR} transparent
737
; Setting the background color to transparent isn't enough to actually make a
738
; checkbox background transparent, you also have to set the right style.
739
${NSD_AddExStyle} $CheckboxCleanupProfile ${WS_EX_TRANSPARENT}
740
; For some reason, clicking on the checkbox causes its text to be redrawn
741
; one pixel to the side of where it was, but without clearing away the
742
; existing text first, so it looks like the weight increases when you click.
743
; Hack around this by manually hiding and then re-showing the textbox when
744
; it gets clicked on.
745
${NSD_OnClick} $CheckboxCleanupProfile RedrawWindow
746
${NSD_Check} $CheckboxCleanupProfile
747
748
; Time to draw the continue button. Compute its height based on the top and
749
; height of the checkbox, since GetDlgItemBottomPX returns nonsense for the
750
; checkbox for some reason.
751
IntOp $1 $1 + $R2
752
; Also add some margin above the button.
753
${DialogUnitsToPixels} ${PROFILE_CLEANUP_BUTTON_TOP_MARGIN} Y $2
754
IntOp $1 $1 + $2
755
; Determine the size of the button.
756
${GetTextExtent} $ProfileCleanupButtonString $FontFooter $R1 $R2
757
; Add some padding around the text for both dimensions.
758
${DialogUnitsToPixels} ${PROFILE_CLEANUP_BUTTON_X_PADDING} X $2
759
IntOp $R1 $R1 + $2
760
${DialogUnitsToPixels} ${PROFILE_CLEANUP_BUTTON_Y_PADDING} Y $2
761
IntOp $R2 $R2 + $2
762
${If} ${PROFILE_CLEANUP_BUTTON_LEFT} == "center"
763
${GetDlgItemWidthHeight} $HWNDPARENT $R3 $R4
764
IntOp $R5 $R1 / 2
765
IntOp $R3 $R3 / 2
766
IntOp $R3 $R3 - $R5
767
${Else}
768
${ConvertLeftCoordForRTL} ${PROFILE_CLEANUP_BUTTON_LEFT} $R1 $R3
769
${EndIf}
770
; We need a custom button because the default ones get drawn underneath the
771
; background image we're about to insert.
772
${NSD_CreateButton} $R3 $1 $R1 $R2 "$ProfileCleanupButtonString"
773
Pop $0
774
SendMessage $0 ${WM_SETFONT} $FontButton 0
775
${NSD_OnClick} $0 gotoInstallPage
776
${NSD_SetFocus} $0
777
778
; Draw the footer text.
779
!ifdef INSTALL_FOOTER_WIDTH
780
${GetTextWidthHeight} "$(STUB_BLURB_FOOTER2)" $FontFooter \
781
${INSTALL_FOOTER_WIDTH} $R1 $R2
782
!ifdef ${AB_CD}_rtl
783
nsDialogs::CreateControl STATIC ${DEFAULT_STYLES}|${SS_NOTIFY} \
784
${WS_EX_TRANSPARENT} 30u ${INSTALL_FOOTER_TOP} ${INSTALL_FOOTER_WIDTH} \
785
"$R2" "$(STUB_BLURB_FOOTER2)"
786
!else
787
nsDialogs::CreateControl STATIC ${DEFAULT_STYLES}|${SS_NOTIFY}|${SS_RIGHT} \
788
${WS_EX_TRANSPARENT} 175u ${INSTALL_FOOTER_TOP} ${INSTALL_FOOTER_WIDTH} \
789
"$R2" "$(STUB_BLURB_FOOTER2)"
790
!endif
791
Pop $0
792
SendMessage $0 ${WM_SETFONT} $FontFooter 0
793
SetCtlColors $0 ${COMMON_TEXT_COLOR} transparent
794
!endif
795
796
${If} $UsingHighContrastMode == 0
797
Call DrawBackgroundImage
798
${EndIf}
799
800
LockWindow off
801
nsDialogs::Show
802
803
${If} $UsingHighContrastMode == 0
804
${NSD_FreeImage} $BgBitmapImage
805
${EndIf}
806
FunctionEnd
807
808
Function RedrawWindow
809
Pop $0
810
ShowWindow $0 ${SW_HIDE}
811
ShowWindow $0 ${SW_SHOW}
812
FunctionEnd
813
814
Function gotoInstallPage
815
; Eat the parameter that NSD_OnClick always passes but that we don't need.
816
Pop $0
817
818
; Save the state of the checkbox before it's destroyed.
819
${NSD_GetState} $CheckboxCleanupProfile $CheckboxCleanupProfile
820
821
StrCpy $R9 1
822
Call RelativeGotoPage
823
FunctionEnd
824
825
Function createInstall
826
; Begin setting up the download/install window
827
828
nsDialogs::Create /NOUNLOAD 1018
829
Pop $Dialog
830
831
SetCtlColors $HWNDPARENT ${COMMON_TEXT_COLOR} ${COMMON_BACKGROUND_COLOR}
832
833
; Since the text color for controls is set in this Dialog the foreground and
834
; background colors of the Dialog must also be hardcoded.
835
SetCtlColors $Dialog ${COMMON_TEXT_COLOR} ${COMMON_BACKGROUND_COLOR}
836
837
FindWindow $7 "#32770" "" $HWNDPARENT
838
${GetDlgItemWidthHeight} $HWNDPARENT $8 $9
839
840
; Resize the Dialog to fill the entire window
841
System::Call 'user32::MoveWindow(i$Dialog,i0,i0,i $8,i $9,i0)'
842
843
!ifdef INSTALL_HEADER_WIDTH
844
; Draw the header text.
845
${DialogUnitsToPixels} ${INSTALL_HEADER_WIDTH} X $0
846
${GetTextWidthHeight} "$(STUB_INSTALLING_HEADLINE)" $FontHeader $0 $R1 $R2
847
${ConvertLeftCoordForRTL} ${INSTALL_HEADER_LEFT} $0 $9
848
; If this text is over the maximum height, drop the font size until it fits.
849
StrCpy $4 $FontHeader
850
!ifdef INSTALL_HEADER_HEIGHT
851
${DialogUnitsToPixels} ${INSTALL_HEADER_HEIGHT} Y $2
852
StrCpy $3 ${INSTALL_HEADER_FONT_SIZE}
853
${While} $R2 > $2
854
IntOp $3 $3 - 2
855
CreateFont $4 "$FontFamilyName" $3 ${INSTALL_HEADER_FONT_WEIGHT}
856
${GetTextWidthHeight} "$(STUB_INSTALLING_HEADLINE)" $4 $0 $R1 $R2
857
${EndWhile}
858
!endif
859
${NSD_CreateLabel} $9 ${INSTALL_HEADER_TOP} $0 $R2 \
860
"$(STUB_INSTALLING_HEADLINE)"
861
Pop $0
862
SendMessage $0 ${WM_SETFONT} $4 0
863
SetCtlColors $0 ${COMMON_TEXT_COLOR} transparent
864
!endif
865
866
!ifdef INSTALL_BODY_WIDTH
867
; Draw the body text the same way as the header, but we also need to work
868
; out where to put it based on where the bottom of the header is.
869
${GetDlgItemBottomPX} $0 $1
870
; Add a bit of padding above this text.
871
${DialogUnitsToPixels} ${INSTALL_BODY_TOP_MARGIN} Y $2
872
IntOp $1 $1 + $2
873
${DialogUnitsToPixels} ${INSTALL_BODY_WIDTH} X $0
874
${GetTextWidthHeight} "$(STUB_INSTALLING_BODY)" $FontCheckbox $0 $R1 $R2
875
${ConvertLeftCoordForRTL} ${INSTALL_BODY_LEFT} $0 $9
876
${NSD_CreateLabel} $9 $1 ${INSTALL_BODY_WIDTH} $R2 "$(STUB_INSTALLING_BODY)"
877
Pop $0
878
SendMessage $0 ${WM_SETFONT} $FontCheckbox 0
879
SetCtlColors $0 ${COMMON_TEXT_COLOR} transparent
880
!endif
881
882
; Draw the "Now installing" text
883
!if ${INSTALL_INSTALLING_WIDTH} == "100%"
884
${GetDlgItemWidthHeight} $HWNDPARENT $0 $1
885
!else
886
${DialogUnitsToPixels} ${INSTALL_INSTALLING_WIDTH} X $0
887
!endif
888
${GetTextWidthHeight} "$(STUB_INSTALLING_LABEL2)" $FontInstalling $0 $R1 $R2
889
${ConvertLeftCoordForRTL} ${INSTALL_INSTALLING_LEFT} $0 $9
890
${NSD_CreateLabelCenter} $9 ${INSTALL_INSTALLING_TOP} \
891
${INSTALL_INSTALLING_WIDTH} $R2 "$(STUB_INSTALLING_LABEL2)"
892
Pop $0
893
SendMessage $0 ${WM_SETFONT} $FontInstalling 0
894
${If} $UsingHighContrastMode == 0
895
SetCtlColors $0 ${INSTALL_INSTALLING_TEXT_COLOR} transparent
896
${Else}
897
SetCtlColors $0 ${COMMON_TEXT_COLOR} transparent
898
${EndIf}
899
900
; Initialize these variables even if we won't use them to silence warnings.
901
StrCpy $CurrentBlurbIdx "0"
902
StrCpy $LabelBlurb "0"
903
!ifdef INSTALL_BLURB_WIDTH
904
${NSD_CreateLabelCenter} 0% ${INSTALL_BLURB_TOP} 100% ${INSTALL_BLURB_WIDTH} \
905
"$(STUB_BLURB_FIRST1)"
906
Pop $LabelBlurb
907
SendMessage $LabelBlurb ${WM_SETFONT} $FontBlurb 0
908
SetCtlColors $LabelBlurb ${COMMON_TEXT_COLOR} transparent
909
${NSD_CreateTimer} ClearBlurb ${BlurbDisplayMS}
910
!endif
911
912
!ifdef INSTALL_FOOTER_WIDTH
913
${GetTextWidthHeight} "$(STUB_BLURB_FOOTER2)" $FontFooter \
914
${INSTALL_FOOTER_WIDTH} $R1 $R2
915
!ifdef ${AB_CD}_rtl
916
nsDialogs::CreateControl STATIC ${DEFAULT_STYLES}|${SS_NOTIFY} \
917
${WS_EX_TRANSPARENT} 30u ${INSTALL_FOOTER_TOP} \
918
${INSTALL_FOOTER_WIDTH} "$R2u" "$(STUB_BLURB_FOOTER2)"
919
!else
920
nsDialogs::CreateControl STATIC ${DEFAULT_STYLES}|${SS_NOTIFY}|${SS_RIGHT} \
921
${WS_EX_TRANSPARENT} 175u ${INSTALL_FOOTER_TOP} \
922
${INSTALL_FOOTER_WIDTH} "$R2u" "$(STUB_BLURB_FOOTER2)"
923
!endif
924
Pop $0
925
SendMessage $0 ${WM_SETFONT} $FontFooter 0
926
SetCtlColors $0 ${COMMON_TEXT_COLOR} transparent
927
!endif
928
929
; And now draw the progress bar.
930
ClearErrors
931
${WordFind} "${INSTALL_PROGRESS_BAR_WIDTH}" "%" "E#" $9
932
${If} ${Errors}
933
${ConvertLeftCoordForRTL} ${INSTALL_PROGRESS_BAR_LEFT} ${INSTALL_PROGRESS_BAR_WIDTH} $9
934
${Else}
935
StrCpy $9 "${INSTALL_PROGRESS_BAR_LEFT}"
936
${EndIf}
937
${NSD_CreateProgressBar} $9 ${INSTALL_PROGRESS_BAR_TOP} \
938
${INSTALL_PROGRESS_BAR_WIDTH} ${INSTALL_PROGRESS_BAR_HEIGHT} ""
939
Pop $Progressbar
940
!ifdef PROGRESS_BAR_BACKGROUND_COLOR
941
; The uxtheme must be disabled so we can change the color.
942
System::Call 'uxtheme::SetWindowTheme(i $Progressbar, w " ", w " ")'
943
SendMessage $Progressbar ${PBM_SETBARCOLOR} 0 ${PROGRESS_BAR_BACKGROUND_COLOR}
944
!endif
945
${NSD_AddStyle} $Progressbar ${PBS_MARQUEE}
946
SendMessage $Progressbar ${PBM_SETMARQUEE} 1 \
947
$ProgressbarMarqueeIntervalMS ; start=1|stop=0 interval(ms)=+N
948
949
${If} $UsingHighContrastMode == 0
950
Call DrawBackgroundImage
951
${EndIf}
952
953
GetDlgItem $0 $HWNDPARENT 1 ; Install button
954
EnableWindow $0 0
955
ShowWindow $0 ${SW_HIDE}
956
957
GetDlgItem $0 $HWNDPARENT 3 ; Back button
958
EnableWindow $0 0
959
ShowWindow $0 ${SW_HIDE}
960
961
GetDlgItem $0 $HWNDPARENT 2 ; Cancel button
962
; Focus the Cancel button otherwise it isn't possible to tab to it since it is
963
; the only control that can be tabbed to.
964
${NSD_SetFocus} $0
965
; Kill the Cancel button's focus so pressing enter won't cancel the install.
966
SendMessage $0 ${WM_KILLFOCUS} 0 0
967
; Hide the Cancel button, but don't disable it (or else it won't be possible
968
; to close the window)
969
ShowWindow $0 ${SW_HIDE}
970
971
GetDlgItem $0 $HWNDPARENT 10 ; Default browser checkbox
972
; Hiding and then disabling allows Esc to still exit the installer
973
ShowWindow $0 ${SW_HIDE}
974
EnableWindow $0 0
975
976
GetDlgItem $0 $HWNDPARENT 11 ; Footer text
977
ShowWindow $0 ${SW_HIDE}
978
EnableWindow $0 0
979
980
; Set $DownloadReset to true so the first download tick count is measured.
981
StrCpy $DownloadReset "true"
982
StrCpy $IsDownloadFinished "false"
983
StrCpy $DownloadRetryCount "0"
984
StrCpy $DownloadedBytes "0"
985
StrCpy $StartLastDownloadTickCount ""
986
StrCpy $DownloadFirstTransferSeconds ""
987
StrCpy $OpenedDownloadPage "0"
988
989
ClearErrors
990
ReadINIStr $ExistingVersion "$INSTDIR\application.ini" "App" "Version"
991
${If} ${Errors}
992
StrCpy $ExistingVersion "0"
993
${EndIf}
994
995
ClearErrors
996
ReadINIStr $ExistingBuildID "$INSTDIR\application.ini" "App" "BuildID"
997
${If} ${Errors}
998
StrCpy $ExistingBuildID "0"
999
${EndIf}
1000
1001
${If} ${FileExists} "$LOCALAPPDATA\Mozilla\Firefox"
1002
StrCpy $ExistingProfile "1"
1003
${Else}
1004
StrCpy $ExistingProfile "0"
1005
${EndIf}
1006
1007
StrCpy $DownloadServerIP ""
1008
1009
System::Call "kernel32::GetTickCount()l .s"
1010
Pop $StartDownloadPhaseTickCount
1011
1012
${If} ${FileExists} "$INSTDIR\uninstall\uninstall.log"
1013
StrCpy $InstallTotalSteps ${InstallPaveOverTotalSteps}
1014
${Else}
1015
StrCpy $InstallTotalSteps ${InstallCleanTotalSteps}
1016
${EndIf}
1017
1018
${ITBL3Create}
1019
${ITBL3SetProgressState} "${TBPF_INDETERMINATE}"
1020
1021
; Make sure the file we're about to try to download to doesn't already exist,
1022
; so we don't end up trying to "resume" on top of the wrong file.
1023
Delete "$PLUGINSDIR\download.exe"
1024
${NSD_CreateTimer} StartDownload ${DownloadIntervalMS}
1025
1026
LockWindow off
1027
nsDialogs::Show
1028
1029
${If} $UsingHighContrastMode == 0
1030
${NSD_FreeImage} $BgBitmapImage
1031
${EndIf}
1032
FunctionEnd
1033
1034
Function StartDownload
1035
${NSD_KillTimer} StartDownload
1036
Call GetDownloadURL
1037
Pop $0
1038
InetBgDL::Get "$0" "$PLUGINSDIR\download.exe" \
1039
/CONNECTTIMEOUT 120 /RECEIVETIMEOUT 120 /END
1040
StrCpy $4 ""
1041
${NSD_CreateTimer} OnDownload ${DownloadIntervalMS}
1042
${If} ${FileExists} "$INSTDIR\${TO_BE_DELETED}"
1043
RmDir /r "$INSTDIR\${TO_BE_DELETED}"
1044
${EndIf}
1045
FunctionEnd
1046
1047
Function SetProgressBars
1048
SendMessage $Progressbar ${PBM_SETPOS} $ProgressCompleted 0
1049
${ITBL3SetProgressValue} "$ProgressCompleted" "${PROGRESS_BAR_TOTAL_STEPS}"
1050
FunctionEnd
1051
1052
Function NextBlurb
1053
${NSD_KillTimer} NextBlurb
1054
1055
IntOp $CurrentBlurbIdx $CurrentBlurbIdx + 1
1056
IntOp $CurrentBlurbIdx $CurrentBlurbIdx % 3
1057
1058
${If} $CurrentBlurbIdx == "0"
1059
StrCpy $0 "$(STUB_BLURB_FIRST1)"
1060
${ElseIf} $CurrentBlurbIdx == "1"
1061
StrCpy $0 "$(STUB_BLURB_SECOND1)"
1062
${ElseIf} $CurrentBlurbIdx == "2"
1063
StrCpy $0 "$(STUB_BLURB_THIRD1)"
1064
${EndIf}
1065
1066
SendMessage $LabelBlurb ${WM_SETTEXT} 0 "STR:$0"
1067
1068
${NSD_CreateTimer} ClearBlurb ${BlurbDisplayMS}
1069
FunctionEnd
1070
1071
Function ClearBlurb
1072
${NSD_KillTimer} ClearBlurb
1073
1074
SendMessage $LabelBlurb ${WM_SETTEXT} 0 "STR:"
1075
1076
; force the background to repaint to clear the transparent label
1077
System::Call "*(i,i,i,i) p .r0"
1078
System::Call "user32::GetWindowRect(p $LabelBlurb, p r0)"
1079
System::Call "user32::MapWindowPoints(p 0, p $HwndBgBitmapControl, p r0, i 2)"
1080
System::Call "user32::InvalidateRect(p $HwndBgBitmapControl, p r0, i 0)"
1081
System::Free $0
1082
1083
${NSD_CreateTimer} NextBlurb ${BlurbBlankMS}
1084
FunctionEnd
1085
1086
Function OnDownload
1087
InetBgDL::GetStats
1088
# $0 = HTTP status code, 0=Completed
1089
# $1 = Completed files
1090
# $2 = Remaining files
1091
# $3 = Number of downloaded bytes for the current file
1092
# $4 = Size of current file (Empty string if the size is unknown)
1093
# /RESET must be used if status $0 > 299 (e.g. failure), even if resuming
1094
# When status is $0 =< 299 it is handled by InetBgDL
1095
StrCpy $DownloadServerIP "$5"
1096
${If} $0 > 299
1097
${NSD_KillTimer} OnDownload
1098
IntOp $DownloadRetryCount $DownloadRetryCount + 1
1099
${If} $DownloadRetryCount >= ${DownloadMaxRetries}
1100
StrCpy $ExitCode "${ERR_DOWNLOAD_TOO_MANY_RETRIES}"
1101
; Use a timer so the UI has a chance to update
1102
${NSD_CreateTimer} DisplayDownloadError ${InstallIntervalMS}
1103
Return
1104
${EndIf}
1105
1106
; 1000 is a special code meaning InetBgDL lost the connection before it got
1107
; all the bytes it was expecting. We'll try to resume the transfer in that
1108
; case (assuming we aren't out of retries), so don't treat it as a reset
1109
; or clear the progress bar.
1110
${If} $0 != 1000
1111
${If} "$DownloadReset" != "true"
1112
StrCpy $DownloadedBytes "0"
1113
${NSD_AddStyle} $Progressbar ${PBS_MARQUEE}
1114
SendMessage $Progressbar ${PBM_SETMARQUEE} 1 \
1115
$ProgressbarMarqueeIntervalMS ; start=1|stop=0 interval(ms)=+N
1116
${ITBL3SetProgressState} "${TBPF_INDETERMINATE}"
1117
${EndIf}
1118
StrCpy $DownloadSizeBytes ""
1119
StrCpy $DownloadReset "true"
1120
Delete "$PLUGINSDIR\download.exe"
1121
${EndIf}
1122
1123
InetBgDL::Get /RESET /END
1124
${NSD_CreateTimer} StartDownload ${DownloadRetryIntervalMS}
1125
Return
1126
${EndIf}
1127
1128
${If} "$DownloadReset" == "true"
1129
System::Call "kernel32::GetTickCount()l .s"
1130
Pop $StartLastDownloadTickCount
1131
StrCpy $DownloadReset "false"
1132
; The seconds elapsed from the start of the download phase until the first
1133
; bytes are received are only recorded for the first request so it is
1134
; possible to determine connection issues for the first request.
1135
${If} "$DownloadFirstTransferSeconds" == ""
1136
; Get the seconds elapsed from the start of the download phase until the
1137
; first bytes are received.
1138
${GetSecondsElapsed} "$StartDownloadPhaseTickCount" "$StartLastDownloadTickCount" $DownloadFirstTransferSeconds
1139
${EndIf}
1140
${EndIf}
1141
1142
${If} "$DownloadSizeBytes" == ""
1143
${AndIf} "$4" != ""
1144
; Handle the case where the size of the file to be downloaded is less than
1145
; the minimum expected size or greater than the maximum expected size at the
1146
; beginning of the download.
1147
${If} $4 < ${DownloadMinSizeBytes}
1148
${OrIf} $4 > ${DownloadMaxSizeBytes}
1149
${NSD_KillTimer} OnDownload
1150
InetBgDL::Get /RESET /END
1151
StrCpy $DownloadReset "true"
1152
1153
${If} $DownloadRetryCount >= ${DownloadMaxRetries}
1154
; Use a timer so the UI has a chance to update
1155
${NSD_CreateTimer} DisplayDownloadError ${InstallIntervalMS}
1156
${Else}
1157
${NSD_CreateTimer} StartDownload ${DownloadIntervalMS}
1158
${EndIf}
1159
Return
1160
${EndIf}
1161
1162
StrCpy $DownloadSizeBytes "$4"
1163
SendMessage $Progressbar ${PBM_SETMARQUEE} 0 0 ; start=1|stop=0 interval(ms)=+N
1164
${RemoveStyle} $Progressbar ${PBS_MARQUEE}
1165
StrCpy $ProgressCompleted 0
1166
SendMessage $Progressbar ${PBM_SETRANGE32} $ProgressCompleted ${PROGRESS_BAR_TOTAL_STEPS}
1167
${EndIf}
1168
1169
; Don't update the status until after the download starts
1170
${If} $2 != 0
1171
${AndIf} "$4" == ""
1172
Return
1173
${EndIf}
1174
1175
; Handle the case where the downloaded size is greater than the maximum
1176
; expected size during the download.
1177
${If} $DownloadedBytes > ${DownloadMaxSizeBytes}
1178
InetBgDL::Get /RESET /END
1179
StrCpy $DownloadReset "true"
1180
1181
${If} $DownloadRetryCount >= ${DownloadMaxRetries}
1182
; Use a timer so the UI has a chance to update
1183
${NSD_CreateTimer} DisplayDownloadError ${InstallIntervalMS}
1184
${Else}
1185
${NSD_CreateTimer} StartDownload ${DownloadIntervalMS}
1186
${EndIf}
1187
Return
1188
${EndIf}
1189
1190
${If} $IsDownloadFinished != "true"
1191
${If} $2 == 0
1192
${NSD_KillTimer} OnDownload
1193
StrCpy $IsDownloadFinished "true"
1194
System::Call "kernel32::GetTickCount()l .s"
1195
Pop $EndDownloadPhaseTickCount
1196
1197
StrCpy $DownloadedBytes "$DownloadSizeBytes"
1198
1199
; When a download has finished handle the case where the downloaded size
1200
; is less than the minimum expected size or greater than the maximum
1201
; expected size during the download.
1202
${If} $DownloadedBytes < ${DownloadMinSizeBytes}
1203
${OrIf} $DownloadedBytes > ${DownloadMaxSizeBytes}
1204
InetBgDL::Get /RESET /END
1205
StrCpy $DownloadReset "true"
1206
1207
${If} $DownloadRetryCount >= ${DownloadMaxRetries}
1208
; Use a timer so the UI has a chance to update
1209
${NSD_CreateTimer} DisplayDownloadError ${InstallIntervalMS}
1210
${Else}
1211
${NSD_CreateTimer} StartDownload ${DownloadIntervalMS}
1212
${EndIf}
1213
Return
1214
${EndIf}
1215
1216
; Update the progress bars first in the UI change so they take affect
1217
; before other UI changes.
1218
StrCpy $ProgressCompleted "${PROGRESS_BAR_DOWNLOAD_END_STEP}"
1219
Call SetProgressBars
1220
1221
; Disable the Cancel button during the install
1222
GetDlgItem $5 $HWNDPARENT 2
1223
EnableWindow $5 0
1224
1225
; Open a handle to prevent modification of the full installer
1226
StrCpy $R9 "${INVALID_HANDLE_VALUE}"
1227
System::Call 'kernel32::CreateFileW(w "$PLUGINSDIR\download.exe", \
1228
i ${GENERIC_READ}, \
1229
i ${FILE_SHARE_READ}, i 0, \
1230
i ${OPEN_EXISTING}, i 0, i 0) i .R9'
1231
StrCpy $HandleDownload "$R9"
1232
1233
${If} $HandleDownload == ${INVALID_HANDLE_VALUE}
1234
StrCpy $ExitCode "${ERR_PREINSTALL_INVALID_HANDLE}"
1235
System::Call "kernel32::GetTickCount()l .s"
1236
Pop $EndPreInstallPhaseTickCount
1237
; Use a timer so the UI has a chance to update
1238
${NSD_CreateTimer} DisplayDownloadError ${InstallIntervalMS}
1239
${Else}
1240
CertCheck::CheckPETrustAndInfoAsync "$PLUGINSDIR\download.exe" \
1241
"${CertNameDownload}" "${CertIssuerDownload}"
1242
${NSD_CreateTimer} OnCertCheck ${DownloadIntervalMS}
1243
${EndIf}
1244
${Else}
1245
StrCpy $DownloadedBytes "$3"
1246
System::Int64Op $DownloadedBytes * ${PROGRESS_BAR_DOWNLOAD_END_STEP}
1247
Pop $ProgressCompleted
1248
System::Int64Op $ProgressCompleted / $DownloadSizeBytes
1249
Pop $ProgressCompleted
1250
Call SetProgressBars
1251
${EndIf}
1252
${EndIf}
1253
FunctionEnd
1254
1255
Function OnCertCheck
1256
System::Call "kernel32::GetTickCount()l .s"
1257
Pop $EndPreInstallPhaseTickCount
1258
1259
CertCheck::GetStatus
1260
Pop $0
1261
${If} $0 == 0
1262
${GetSecondsElapsed} "$EndDownloadPhaseTickCount" "$EndPreInstallPhaseTickCount" $0
1263
${If} $0 >= ${PreinstallCertCheckMaxWaitSec}
1264
${NSD_KillTimer} OnCertCheck
1265
StrCpy $ExitCode "${ERR_PREINSTALL_CERT_TIMEOUT}"
1266
; Use a timer so the UI has a chance to update
1267
${NSD_CreateTimer} DisplayDownloadError ${InstallIntervalMS}
1268
${EndIf}
1269
Return
1270
${EndIf}
1271
Pop $0
1272
Pop $1
1273
1274
${If} $0 == 0
1275
${AndIf} $1 == 0
1276
StrCpy $ExitCode "${ERR_PREINSTALL_CERT_UNTRUSTED_AND_ATTRIBUTES}"
1277
${ElseIf} $0 == 0
1278
StrCpy $ExitCode "${ERR_PREINSTALL_CERT_UNTRUSTED}"
1279
${ElseIf} $1 == 0
1280
StrCpy $ExitCode "${ERR_PREINSTALL_CERT_ATTRIBUTES}"
1281
${EndIf}
1282
1283
${NSD_KillTimer} OnCertCheck
1284
1285
${If} $0 == 0
1286
${OrIf} $1 == 0
1287
; Use a timer so the UI has a chance to update
1288
${NSD_CreateTimer} DisplayDownloadError ${InstallIntervalMS}
1289
Return
1290
${EndIf}
1291
1292
Call LaunchFullInstaller
1293
FunctionEnd
1294
1295
Function LaunchFullInstaller
1296
; Instead of extracting the files we use the downloaded installer to
1297
; install in case it needs to perform operations that the stub doesn't
1298
; know about.
1299
WriteINIStr "$PLUGINSDIR\${CONFIG_INI}" "Install" "InstallDirectoryPath" "$INSTDIR"
1300
; Don't create the QuickLaunch or Taskbar shortcut from the launched installer
1301
WriteINIStr "$PLUGINSDIR\${CONFIG_INI}" "Install" "QuickLaunchShortcut" "false"
1302
1303
; Always create a start menu shortcut, so the user always has some way
1304
; to access the application.
1305
WriteINIStr "$PLUGINSDIR\${CONFIG_INI}" "Install" "StartMenuShortcuts" "true"
1306
1307
; Either avoid or force adding a taskbar pin and desktop shortcut
1308
; based on the checkbox value.
1309
${If} $CheckboxShortcuts == 0
1310
WriteINIStr "$PLUGINSDIR\${CONFIG_INI}" "Install" "TaskbarShortcut" "false"
1311
WriteINIStr "$PLUGINSDIR\${CONFIG_INI}" "Install" "DesktopShortcut" "false"
1312
${Else}
1313
WriteINIStr "$PLUGINSDIR\${CONFIG_INI}" "Install" "TaskbarShortcut" "true"
1314
WriteINIStr "$PLUGINSDIR\${CONFIG_INI}" "Install" "DesktopShortcut" "true"
1315
${EndIf}
1316
1317
!ifdef MOZ_MAINTENANCE_SERVICE
1318
${If} $CheckboxInstallMaintSvc == 1
1319
WriteINIStr "$PLUGINSDIR\${CONFIG_INI}" "Install" "MaintenanceService" "true"
1320
${Else}
1321
WriteINIStr "$PLUGINSDIR\${CONFIG_INI}" "Install" "MaintenanceService" "false"
1322
${EndIf}
1323
!else
1324
WriteINIStr "$PLUGINSDIR\${CONFIG_INI}" "Install" "MaintenanceService" "false"
1325
!endif
1326
1327
; Delete the taskbar shortcut history to ensure we do the right thing based on
1328
; the config file above.
1329
${GetShortcutsLogPath} $0
1330
Delete "$0"
1331
1332
${RemovePrecompleteEntries} "false"
1333
1334
; Delete the install.log and let the full installer create it. When the
1335
; installer closes it we can detect that it has completed.
1336
Delete "$INSTDIR\install.log"
1337
1338
; Delete firefox.exe.moz-upgrade and firefox.exe.moz-delete if it exists
1339
; since it being present will require an OS restart for the full
1340
; installer.
1341
Delete "$INSTDIR\${FileMainEXE}.moz-upgrade"
1342
Delete "$INSTDIR\${FileMainEXE}.moz-delete"
1343
1344
System::Call "kernel32::GetTickCount()l .s"
1345
Pop $EndPreInstallPhaseTickCount
1346
1347
Exec "$\"$PLUGINSDIR\download.exe$\" /LaunchedFromStub /INI=$PLUGINSDIR\${CONFIG_INI}"
1348
${NSD_CreateTimer} CheckInstall ${InstallIntervalMS}
1349
FunctionEnd
1350
1351
Function SendPing
1352
${NSD_KillTimer} NextBlurb
1353
${NSD_KillTimer} ClearBlurb
1354
HideWindow
1355
1356
${If} $CheckboxSendPing == 1
1357
; Get the tick count for the completion of all phases.
1358
System::Call "kernel32::GetTickCount()l .s"
1359
Pop $EndFinishPhaseTickCount
1360
1361
; When the value of $IsDownloadFinished is false the download was started
1362
; but didn't finish. In this case the tick count stored in
1363
; $EndFinishPhaseTickCount is used to determine how long the download was
1364
; in progress.
1365
${If} "$IsDownloadFinished" == "false"
1366
StrCpy $EndDownloadPhaseTickCount "$EndFinishPhaseTickCount"
1367
; Cancel the download in progress
1368
InetBgDL::Get /RESET /END
1369
${EndIf}
1370
1371
1372
; When $DownloadFirstTransferSeconds equals an empty string the download
1373
; never successfully started so set the value to 0. It will be possible to
1374
; determine that the download didn't successfully start from the seconds for
1375
; the last download.
1376
${If} "$DownloadFirstTransferSeconds" == ""
1377
StrCpy $DownloadFirstTransferSeconds "0"
1378
${EndIf}
1379
1380
; When $StartLastDownloadTickCount equals an empty string the download never
1381
; successfully started so set the value to $EndDownloadPhaseTickCount to
1382
; compute the correct value.
1383
${If} $StartLastDownloadTickCount == ""
1384
; This could happen if the download never successfully starts
1385
StrCpy $StartLastDownloadTickCount "$EndDownloadPhaseTickCount"
1386
${EndIf}
1387
1388
; When $EndPreInstallPhaseTickCount equals 0 the installation phase was
1389
; never completed so set its value to $EndFinishPhaseTickCount to compute
1390
; the correct value.
1391
${If} "$EndPreInstallPhaseTickCount" == "0"
1392
StrCpy $EndPreInstallPhaseTickCount "$EndFinishPhaseTickCount"
1393
${EndIf}
1394
1395
; When $EndInstallPhaseTickCount equals 0 the installation phase was never
1396
; completed so set its value to $EndFinishPhaseTickCount to compute the
1397
; correct value.
1398
${If} "$EndInstallPhaseTickCount" == "0"
1399
StrCpy $EndInstallPhaseTickCount "$EndFinishPhaseTickCount"
1400
${EndIf}
1401
1402
; Get the seconds elapsed from the start of the download phase to the end of
1403
; the download phase.
1404
${GetSecondsElapsed} "$StartDownloadPhaseTickCount" "$EndDownloadPhaseTickCount" $0
1405
1406
; Get the seconds elapsed from the start of the last download to the end of
1407
; the last download.
1408
${GetSecondsElapsed} "$StartLastDownloadTickCount" "$EndDownloadPhaseTickCount" $1
1409
1410
; Get the seconds elapsed from the end of the download phase to the
1411
; completion of the pre-installation check phase.
1412
${GetSecondsElapsed} "$EndDownloadPhaseTickCount" "$EndPreInstallPhaseTickCount" $2
1413
1414
; Get the seconds elapsed from the end of the pre-installation check phase
1415
; to the completion of the installation phase.
1416
${GetSecondsElapsed} "$EndPreInstallPhaseTickCount" "$EndInstallPhaseTickCount" $3
1417
1418
; Get the seconds elapsed from the end of the installation phase to the
1419
; completion of all phases.
1420
${GetSecondsElapsed} "$EndInstallPhaseTickCount" "$EndFinishPhaseTickCount" $4
1421
1422
${If} $ArchToInstall == ${ARCH_AMD64}
1423
${OrIf} $ArchToInstall == ${ARCH_AARCH64}
1424
StrCpy $R0 "1"
1425
${Else}
1426
StrCpy $R0 "0"
1427
${EndIf}
1428
1429
${If} ${IsNativeAMD64}
1430
${OrIf} ${IsNativeARM64}
1431
StrCpy $R1 "1"
1432
${Else}
1433
StrCpy $R1 "0"
1434
${EndIf}
1435
1436
; Though these values are sometimes incorrect due to bug 444664 it happens
1437
; so rarely it isn't worth working around it by reading the registry values.
1438
${WinVerGetMajor} $5
1439
${WinVerGetMinor} $6
1440
${WinVerGetBuild} $7
1441
${WinVerGetServicePackLevel} $8
1442
${If} ${IsServerOS}
1443
StrCpy $9 "1"
1444
${Else}
1445
StrCpy $9 "0"
1446
${EndIf}
1447
1448
${If} "$ExitCode" == "${ERR_SUCCESS}"
1449
ReadINIStr $R5 "$INSTDIR\application.ini" "App" "Version"
1450
ReadINIStr $R6 "$INSTDIR\application.ini" "App" "BuildID"
1451
${Else}
1452
StrCpy $R5 "0"
1453
StrCpy $R6 "0"
1454
${EndIf}
1455
1456
; Whether installed into the default installation directory
1457
${GetLongPath} "$INSTDIR" $R7
1458
${GetLongPath} "$InitialInstallDir" $R8
1459
${If} "$R7" == "$R8"
1460
StrCpy $R7 "1"
1461
${Else}
1462
StrCpy $R7 "0"
1463
${EndIf}
1464
1465
ClearErrors
1466
WriteRegStr HKLM "Software\Mozilla" "${BrandShortName}InstallerTest" \
1467
"Write Test"
1468
${If} ${Errors}
1469
StrCpy $R8 "0"
1470
${Else}
1471
DeleteRegValue HKLM "Software\Mozilla" "${BrandShortName}InstallerTest"
1472
StrCpy $R8 "1"
1473
${EndIf}
1474
1475
${If} "$DownloadServerIP" == ""
1476
StrCpy $DownloadServerIP "Unknown"
1477
${EndIf}
1478
1479
StrCpy $R2 ""
1480
SetShellVarContext current ; Set SHCTX to the current user
1481
ReadRegStr $R2 HKCU "Software\Classes\http\shell\open\command" ""
1482
${If} $R2 != ""
1483
${GetPathFromString} "$R2" $R2
1484
${GetParent} "$R2" $R3
1485
${GetLongPath} "$R3" $R3
1486
${If} $R3 == $INSTDIR
1487
StrCpy $R2 "1" ; This Firefox install is set as default.
1488
${Else}
1489
StrCpy $R2 "$R2" "" -11 # length of firefox.exe
1490
${If} "$R2" == "${FileMainEXE}"
1491
StrCpy $R2 "2" ; Another Firefox install is set as default.
1492
${Else}
1493
StrCpy $R2 "0"
1494
${EndIf}
1495
${EndIf}
1496
${Else}
1497
StrCpy $R2 "0" ; Firefox is not set as default.
1498
${EndIf}
1499
1500
${If} "$R2" == "0"
1501
StrCpy $R3 ""
1502
ReadRegStr $R2 HKLM "Software\Classes\http\shell\open\command" ""
1503
${If} $R2 != ""
1504
${GetPathFromString} "$R2" $R2
1505
${GetParent} "$R2" $R3
1506
${GetLongPath} "$R3" $R3
1507
${If} $R3 == $INSTDIR
1508
StrCpy $R2 "1" ; This Firefox install is set as default.
1509
${Else}
1510
StrCpy $R2 "$R2" "" -11 # length of firefox.exe
1511
${If} "$R2" == "${FileMainEXE}"
1512
StrCpy $R2 "2" ; Another Firefox install is set as default.
1513
${Else}
1514
StrCpy $R2 "0"
1515
${EndIf}
1516
${EndIf}
1517
${Else}
1518
StrCpy $R2 "0" ; Firefox is not set as default.
1519
${EndIf}
1520
${EndIf}
1521
1522
${If} $CanSetAsDefault == "true"
1523
${If} $CheckboxSetAsDefault == "1"
1524
StrCpy $R3 "2"
1525
${Else}
1526
StrCpy $R3 "3"
1527
${EndIf}
1528
${Else}
1529
${If} ${AtLeastWin8}
1530
StrCpy $R3 "1"
1531
${Else}
1532
StrCpy $R3 "0"
1533
${EndIf}
1534
${EndIf}
1535
1536
!ifdef STUB_DEBUG
1537
MessageBox MB_OK "${BaseURLStubPing} \
1538
$\nStub URL Version = ${StubURLVersion}${StubURLVersionAppend} \
1539
$\nBuild Channel = ${Channel} \
1540
$\nUpdate Channel = ${UpdateChannel} \
1541
$\nLocale = ${AB_CD} \
1542
$\nFirefox x64 = $R0 \
1543
$\nRunning x64 Windows = $R1 \
1544
$\nMajor = $5 \
1545
$\nMinor = $6 \
1546
$\nBuild = $7 \
1547
$\nServicePack = $8 \
1548
$\nIsServer = $9 \
1549
$\nExit Code = $ExitCode \
1550
$\nFirefox Launch Code = $FirefoxLaunchCode \
1551
$\nDownload Retry Count = $DownloadRetryCount \
1552
$\nDownloaded Bytes = $DownloadedBytes \
1553
$\nDownload Size Bytes = $DownloadSizeBytes \
1554
$\nIntroduction Phase Seconds = $IntroPhaseSeconds \
1555
$\nOptions Phase Seconds = $OptionsPhaseSeconds \
1556
$\nDownload Phase Seconds = $0 \
1557
$\nLast Download Seconds = $1 \
1558
$\nDownload First Transfer Seconds = $DownloadFirstTransferSeconds \
1559
$\nPreinstall Phase Seconds = $2 \
1560
$\nInstall Phase Seconds = $3 \
1561
$\nFinish Phase Seconds = $4 \
1562
$\nInitial Install Requirements Code = $InitialInstallRequirementsCode \
1563
$\nOpened Download Page = $OpenedDownloadPage \
1564
$\nExisting Profile = $ExistingProfile \
1565
$\nExisting Version = $ExistingVersion \
1566
$\nExisting Build ID = $ExistingBuildID \
1567
$\nNew Version = $R5 \
1568
$\nNew Build ID = $R6 \
1569
$\nDefault Install Dir = $R7 \
1570
$\nHas Admin = $R8 \
1571
$\nDefault Status = $R2 \
1572
$\nSet As Sefault Status = $R3 \
1573
$\nDownload Server IP = $DownloadServerIP \
1574
$\nPost-Signing Data = $PostSigningData \
1575
$\nProfile cleanup prompt shown = $ProfileCleanupPromptType \
1576
$\nDid profile cleanup = $CheckboxCleanupProfile"
1577
; The following will exit the installer
1578
SetAutoClose true
1579
StrCpy $R9 "2"
1580
Call RelativeGotoPage
1581
!else
1582
${NSD_CreateTimer} OnPing ${DownloadIntervalMS}
1583
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" \
1584
"$PLUGINSDIR\_temp" /END
1585
!endif
1586
${Else}
1587
${If} "$IsDownloadFinished" == "false"
1588
; Cancel the download in progress
1589
InetBgDL::Get /RESET /END
1590
${EndIf}
1591
; The following will exit the installer
1592
SetAutoClose true
1593
StrCpy $R9 "2"
1594
Call RelativeGotoPage
1595
${EndIf}
1596
FunctionEnd
1597
1598
Function OnPing
1599
InetBgDL::GetStats
1600
# $0 = HTTP status code, 0=Completed
1601
# $1 = Completed files
1602
# $2 = Remaining files
1603
# $3 = Number of downloaded bytes for the current file
1604
# $4 = Size of current file (Empty string if the size is unknown)
1605
# /RESET must be used if status $0 > 299 (e.g. failure)
1606
# When status is $0 =< 299 it is handled by InetBgDL
1607
${If} $2 == 0
1608
${OrIf} $0 > 299
1609
${NSD_KillTimer} OnPing
1610
${If} $0 > 299
1611
InetBgDL::Get /RESET /END
1612
${EndIf}
1613
; The following will exit the installer
1614
SetAutoClose true
1615
StrCpy $R9 "2"
1616
Call RelativeGotoPage
1617
${EndIf}
1618
FunctionEnd
1619
1620
Function CheckInstall
1621
IntOp $InstallCounterStep $InstallCounterStep + 1
1622
${If} $InstallCounterStep >= $InstallTotalSteps
1623
${NSD_KillTimer} CheckInstall
1624
; Close the handle that prevents modification of the full installer
1625
System::Call 'kernel32::CloseHandle(i $HandleDownload)'
1626
StrCpy $ExitCode "${ERR_INSTALL_TIMEOUT}"
1627
; Use a timer so the UI has a chance to update
1628
${NSD_CreateTimer} DisplayDownloadError ${InstallIntervalMS}
1629
Return
1630
${EndIf}
1631
1632
${If} $ProgressCompleted < ${PROGRESS_BAR_INSTALL_END_STEP}
1633
IntOp $0 ${PROGRESS_BAR_INSTALL_END_STEP} - ${PROGRESS_BAR_DOWNLOAD_END_STEP}
1634
IntOp $0 $InstallCounterStep * $0
1635
IntOp $0 $0 / $InstallTotalSteps
1636
IntOp $ProgressCompleted ${PROGRESS_BAR_DOWNLOAD_END_STEP} + $0
1637
Call SetProgressBars
1638
${EndIf}
1639
1640
${If} ${FileExists} "$INSTDIR\install.log"
1641
Delete "$INSTDIR\install.tmp"
1642
CopyFiles /SILENT "$INSTDIR\install.log" "$INSTDIR\install.tmp"
1643
1644
; The unfocus and refocus that happens approximately here is caused by the
1645
; installer calling SHChangeNotify to refresh the shortcut icons.
1646
1647
; When the full installer completes the installation the install.log will no
1648
; longer be in use.
1649
ClearErrors
1650
Delete "$INSTDIR\install.log"
1651
${Unless} ${Errors}
1652
${NSD_KillTimer} CheckInstall
1653
; Close the handle that prevents modification of the full installer
1654
System::Call 'kernel32::CloseHandle(i $HandleDownload)'
1655
Rename "$INSTDIR\install.tmp" "$INSTDIR\install.log"
1656
Delete "$PLUGINSDIR\download.exe"
1657
Delete "$PLUGINSDIR\${CONFIG_INI}"
1658
System::Call "kernel32::GetTickCount()l .s"
1659
Pop $EndInstallPhaseTickCount
1660
Call FinishInstall
1661
${EndUnless}
1662
${EndIf}
1663
FunctionEnd
1664
1665
Function FinishInstall
1666
StrCpy $ProgressCompleted "${PROGRESS_BAR_INSTALL_END_STEP}"
1667
Call SetProgressBars
1668
1669
${If} ${FileExists} "$INSTDIR\${FileMainEXE}.moz-upgrade"
1670
Delete "$INSTDIR\${FileMainEXE}"
1671
Rename "$INSTDIR\${FileMainEXE}.moz-upgrade" "$INSTDIR\${FileMainEXE}"
1672
${EndIf}
1673
1674
StrCpy $ExitCode "${ERR_SUCCESS}"
1675
1676
Call CopyPostSigningData
1677
Call LaunchApp
1678
FunctionEnd
1679
1680
Function RelativeGotoPage
1681
IntCmp $R9 0 0 Move Move
1682
StrCmp $R9 "X" 0 Move
1683
StrCpy $R9 "120"
1684
1685
Move:
1686
SendMessage $HWNDPARENT "0x408" "$R9" ""
1687
FunctionEnd
1688
1689
Function CheckSpace
1690
${If} "$ExistingTopDir" != ""
1691
StrLen $0 "$ExistingTopDir"
1692
StrLen $1 "$INSTDIR"
1693
${If} $0 <= $1
1694
StrCpy $2 "$INSTDIR" $3
1695
${If} "$2" == "$ExistingTopDir"
1696
Return
1697
${EndIf}
1698
${EndIf}
1699
${EndIf}
1700
1701
StrCpy $ExistingTopDir "$INSTDIR"
1702
${DoUntil} ${FileExists} "$ExistingTopDir"
1703
${GetParent} "$ExistingTopDir" $ExistingTopDir
1704
${If} "$ExistingTopDir" == ""
1705
StrCpy $SpaceAvailableBytes "0"
1706
StrCpy $HasRequiredSpaceAvailable "false"
1707
Return
1708
${EndIf}
1709
${Loop}
1710
1711
${GetLongPath} "$ExistingTopDir" $ExistingTopDir
1712
1713
; GetDiskFreeSpaceExW requires a backslash.
1714
StrCpy $0 "$ExistingTopDir" "" -1 ; the last character
1715
${If} "$0" != "\"
1716
StrCpy $0 "\"
1717
${Else}
1718
StrCpy $0 ""
1719
${EndIf}
1720
1721
System::Call 'kernel32::GetDiskFreeSpaceExW(w, *l, *l, *l) i("$ExistingTopDir$0", .r1, .r2, .r3) .'
1722
StrCpy $SpaceAvailableBytes "$1"
1723
1724
System::Int64Op $SpaceAvailableBytes / 1048576
1725
Pop $1
1726
System::Int64Op $1 > ${APPROXIMATE_REQUIRED_SPACE_MB}
1727
Pop $1
1728
${If} $1 == 1
1729
StrCpy $HasRequiredSpaceAvailable "true"
1730
${Else}
1731
StrCpy $HasRequiredSpaceAvailable "false"
1732
${EndIf}
1733
FunctionEnd
1734
1735
Function CanWrite
1736
StrCpy $CanWriteToInstallDir "false"
1737
1738
StrCpy $0 "$INSTDIR"
1739
; Use the existing directory when it exists
1740
${Unless} ${FileExists} "$INSTDIR"
1741
; Get the topmost directory that exists for new installs
1742
${DoUntil} ${FileExists} "$0"
1743
${GetParent} "$0" $0
1744
${If} "$0" == ""
1745
Return
1746
${EndIf}
1747
${Loop}
1748
${EndUnless}
1749
1750
GetTempFileName $2 "$0"
1751
Delete $2
1752
CreateDirectory "$2"
1753
1754
${If} ${FileExists} "$2"
1755
${If} ${FileExists} "$INSTDIR"
1756
GetTempFileName $3 "$INSTDIR"
1757
${Else}
1758
GetTempFileName $3 "$2"
1759
${EndIf}
1760
${If} ${FileExists} "$3"
1761
Delete "$3"
1762
StrCpy $CanWriteToInstallDir "true"
1763
${EndIf}
1764
RmDir "$2"
1765
${EndIf}
1766
FunctionEnd
1767
1768
Function LaunchApp
1769
!ifndef DEV_EDITION
1770
FindWindow $0 "${WindowClass}"
1771
${If} $0 <> 0 ; integer comparison
1772
StrCpy $FirefoxLaunchCode "1"
1773
1774
StrCpy $ProgressCompleted ${PROGRESS_BAR_TOTAL_STEPS}
1775
Call SetProgressBars
1776
1777
MessageBox MB_OK|MB_ICONQUESTION "$(WARN_MANUALLY_CLOSE_APP_LAUNCH)"
1778
Call SendPing
1779
Return
1780
${EndIf}
1781
!endif
1782
1783
StrCpy $FirefoxLaunchCode "2"
1784
1785
; Set the current working directory to the installation directory
1786
SetOutPath "$INSTDIR"
1787
ClearErrors
1788
${GetParameters} $0
1789
${GetOptions} "$0" "/UAC:" $1
1790
${If} ${Errors}
1791
${If} $CheckboxCleanupProfile == 1
1792
${ExecAndWaitForInputIdle} "$\"$INSTDIR\${FileMainEXE}$\" -reset-profile -migration"
1793
${Else}
1794
${ExecAndWaitForInputIdle} "$\"$INSTDIR\${FileMainEXE}$\""
1795
${EndIf}
1796
${Else}
1797
StrCpy $R1 $CheckboxCleanupProfile
1798
GetFunctionAddress $0 LaunchAppFromElevatedProcess
1799
UAC::ExecCodeSegment $0
1800
${EndIf}
1801
1802
StrCpy $AppLaunchWaitTickCount 0
1803
${NSD_CreateTimer} WaitForAppLaunch ${AppLaunchWaitIntervalMS}
1804
FunctionEnd
1805
1806
Function LaunchAppFromElevatedProcess
1807
; Set the current working directory to the installation directory
1808
SetOutPath "$INSTDIR"
1809
${If} $R1 == 1
1810
${ExecAndWaitForInputIdle} "$\"$INSTDIR\${FileMainEXE}$\" -reset-profile -migration"
1811
${Else}
1812
${ExecAndWaitForInputIdle} "$\"$INSTDIR\${FileMainEXE}$\""
1813
${EndIf}
1814
FunctionEnd
1815
1816
Function WaitForAppLaunch
1817
FindWindow $0 "${MainWindowClass}"
1818
FindWindow $1 "${DialogWindowClass}"
1819
${If} $0 <> 0
1820
${OrIf} $1 <> 0
1821
${NSD_KillTimer} WaitForAppLaunch
1822
StrCpy $ProgressCompleted "${PROGRESS_BAR_APP_LAUNCH_END_STEP}"
1823
Call SetProgressBars
1824
Call SendPing
1825
Return
1826
${EndIf}
1827
1828
IntOp $AppLaunchWaitTickCount $AppLaunchWaitTickCount + 1
1829
IntOp $0 $AppLaunchWaitTickCount * ${AppLaunchWaitIntervalMS}
1830
${If} $0 >= ${AppLaunchWaitTimeoutMS}
1831
; We've waited an unreasonably long time, so just exit.
1832
${NSD_KillTimer} WaitForAppLaunch
1833
Call SendPing
1834
Return
1835
${EndIf}
1836
1837
${If} $ProgressCompleted < ${PROGRESS_BAR_APP_LAUNCH_END_STEP}
1838
IntOp $ProgressCompleted $ProgressCompleted + 1
1839
Call SetProgressBars
1840
${EndIf}
1841
FunctionEnd
1842
1843
Function CopyPostSigningData
1844
${LineRead} "$EXEDIR\postSigningData" "1" $PostSigningData
1845
${If} ${Errors}
1846
ClearErrors
1847
StrCpy $PostSigningData "0"
1848
${Else}
1849
CreateDirectory "$LOCALAPPDATA\Mozilla\Firefox"
1850
CopyFiles /SILENT "$EXEDIR\postSigningData" "$LOCALAPPDATA\Mozilla\Firefox"
1851
${Endif}
1852
FunctionEnd
1853
1854
Function DisplayDownloadError
1855
${NSD_KillTimer} DisplayDownloadError
1856
${NSD_KillTimer} NextBlurb
1857
${NSD_KillTimer} ClearBlurb
1858
; To better display the error state on the taskbar set the progress completed
1859
; value to the total value.
1860
${ITBL3SetProgressValue} "100" "100"
1861
${ITBL3SetProgressState} "${TBPF_ERROR}"
1862
1863
MessageBox MB_OKCANCEL|MB_ICONSTOP "$(ERROR_DOWNLOAD_CONT)" IDCANCEL +2 IDOK +1
1864
Call LaunchHelpPage
1865
Call SendPing
1866
FunctionEnd
1867
1868
Function LaunchHelpPage
1869
StrCpy $OpenedDownloadPage "1" ; Already initialized to 0
1870
ClearErrors
1871
${GetParameters} $0
1872
${GetOptions} "$0" "/UAC:" $1
1873
${If} ${Errors}
1874
Call OpenManualDownloadURL
1875
${Else}
1876
GetFunctionAddress $0 OpenManualDownloadURL
1877
UAC::ExecCodeSegment $0
1878
${EndIf}
1879
FunctionEnd
1880
1881
Function OpenManualDownloadURL
1882
ClearErrors
1883
ReadINIStr $0 "${PARTNER_INI}" "DownloadURL" "FallbackPage"
1884
${IfNot} ${Errors}
1885
ExecShell "open" "$0"
1886
${Else}
1887
ExecShell "open" "${URLManualDownload}${URLManualDownloadAppend}"
1888
${EndIf}
1889
FunctionEnd
1890
1891
Function ShouldPromptForProfileCleanup
1892
; This will be our return value.
1893
StrCpy $ProfileCleanupPromptType 0
1894
1895
; Only consider installations of the same architecture we're installing.
1896
${If} $ArchToInstall == ${ARCH_AMD64}
1897
${OrIf} $ArchToInstall == ${ARCH_AARCH64}
1898
SetRegView 64
1899
${Else}
1900
SetRegView 32
1901
${EndIf}
1902
1903
; Make sure $APPDATA is the user's AppData and not ProgramData.
1904
; We'll set this back to all at the end of the function.
1905
SetShellVarContext current
1906
1907
StrCpy $R0 ""
1908
; First look for an install-specific profile, which might be listed as
1909
; either a relative or an absolute path (installs.ini doesn't say which).
1910
${If} ${FileExists} "$APPDATA\Mozilla\Firefox\installs.ini"
1911
ClearErrors
1912
ReadINIStr $1 "$APPDATA\Mozilla\Firefox\installs.ini" "$AppUserModelID" "Default"
1913
${IfNot} ${Errors}
1914
${GetLongPath} "$APPDATA\Mozilla\Firefox\$1" $2
1915
${If} ${FileExists} $2
1916
StrCpy $R0 $2
1917
${Else}
1918
${GetLongPath} "$1" $2
1919
${If} ${FileExists} $2
1920
StrCpy $R0 $2
1921
${EndIf}
1922
${EndIf}
1923
${EndIf}
1924
${EndIf}
1925
1926
${If} $R0 == ""
1927
; We don't have an install-specific profile, so look for an old-style
1928
; default profile instead by checking each numbered Profile section.
1929
StrCpy $0 0
1930
${Do}
1931
ClearErrors
1932
; Check if the section exists by reading a value that must be present.
1933
ReadINIStr $1 "$APPDATA\Mozilla\Firefox\profiles.ini" "Profile$0" "Path"
1934
${If} ${Errors}
1935
; We've run out of profile sections.
1936
${Break}
1937
${EndIf}
1938
1939
ClearErrors
1940
ReadINIStr $1 "$APPDATA\Mozilla\Firefox\profiles.ini" "Profile$0" "Default"
1941
${IfNot} ${Errors}
1942
${AndIf} $1 == "1"
1943
; We've found the default profile
1944
ReadINIStr $1 "$APPDATA\Mozilla\Firefox\profiles.ini" "Profile$0" "Path"
1945
ReadINIStr $2 "$APPDATA\Mozilla\Firefox\profiles.ini" "Profile$0" "IsRelative"
1946
${If} $2 == "1"
1947
StrCpy $R0 "$APPDATA\Mozilla\Firefox\$1"
1948
${Else}
1949
StrCpy $R0 "$1"
1950
${EndIf}
1951
${Break}
1952
${EndIf}
1953
1954
IntOp $0 $0 + 1
1955
${Loop}
1956
${EndIf}
1957
1958
GetFullPathName $R0 $R0
1959
1960
${If} $R0 == ""
1961
; No profile to clean up, so don't show the cleanup prompt.
1962
GoTo end
1963
${EndIf}
1964
1965
; We have at least one profile present. If we don't have any installations,
1966
; then we need to show the re-install prompt. We'll say there's an
1967
; installation present if HKCR\FirefoxURL* exists and points to a real path.
1968
StrCpy $0 0
1969
StrCpy $R9 ""
1970
${Do}
1971
ClearErrors
1972
EnumRegKey $1 HKCR "" $0
1973
${If} ${Errors}
1974
${OrIf} $1 == ""
1975
${Break}
1976
${EndIf}
1977
${WordFind} "$1" "-" "+1{" $2
1978
${If} $2 == "FirefoxURL"
1979
ClearErrors
1980
ReadRegStr $2 HKCR "$1\DefaultIcon" ""
1981
${IfNot} ${Errors}
1982
${GetPathFromString} $2 $1
1983
${If} ${FileExists} $1
1984
StrCpy $R9 $1
1985
${Break}
1986
${EndIf}
1987
${EndIf}
1988
${EndIf}
1989
IntOp $0 $0 + 1
1990
${Loop}
1991
${If} $R9 == ""
1992
StrCpy $ProfileCleanupPromptType 1
1993
GoTo end
1994
${EndIf}
1995
1996
; Okay, there's at least one install, let's see if it's for this channel.
1997
SetShellVarContext all
1998
${GetSingleInstallPath} "Software\Mozilla\${BrandFullNameInternal}" $0
1999
${If} $0 == "false"
2000
SetShellVarContext current
2001
${GetSingleInstallPath} "Software\Mozilla\${BrandFullNameInternal}" $0
2002
${If} $0 == "false"
2003
; Existing installs are not for this channel. Don't show any prompt.
2004
GoTo end
2005
${EndIf}
2006
${EndIf}
2007
2008
; Find out what version the default profile was last used on.
2009
${If} ${FileExists} "$R0\compatibility.ini"
2010
ClearErrors
2011
ReadINIStr $0 "$R0\compatibility.ini" "Compatibility" "LastVersion"
2012
${If} ${Errors}
2013
GoTo end
2014
${EndIf}
2015
${WordFind} $0 "." "+1{" $0
2016
2017
; We don't know what version we're about to install because we haven't
2018
; downloaded it yet. Find out what the latest version released on this
2019
; channel is and assume we'll be installing that one.
2020
Call GetLatestReleasedVersion
2021
${If} ${Errors}
2022
; Use this stub installer's version as a fallback when we can't get the
2023
; real current version; this may be behind, but it's better than nothing.
2024
StrCpy $1 ${AppVersion}
2025
${EndIf}
2026
2027
${WordFind} $1 "." "+1{" $1
2028
IntOp $1 $1 - 2
2029
2030
${If} $1 > $0
2031
; Default profile was last used more than two versions ago, so we need
2032
; to show the paveover version of the profile cleanup prompt.
2033
StrCpy $ProfileCleanupPromptType 2
2034
${EndIf}
2035
${EndIf}
2036
2037
end:
2038
SetRegView lastused
2039
SetShellVarContext all
2040
FunctionEnd
2041
2042
Function GetLatestReleasedVersion
2043
ClearErrors
2044
Push $0 ; InetBgDl::GetStats uses $0 for the HTTP error code
2045
; $1 is our return value, so don't save it
2046
Push $2 ; InetBgDl::GetStats uses $2 to tell us when the transfer is done
2047
Push $3 ; $3 - $5 are also set by InetBgDl::GetStats, but we don't use them
2048
Push $4
2049
Push $5
2050
Push $6 ; This is our response timeout counter
2051
2052
InetBgDL::Get /RESET /END
2054
"$PLUGINSDIR\firefox_versions.json" \
2055
/CONNECTTIMEOUT 120 /RECEIVETIMEOUT 120 /END
2056
2057
; Wait for the response, but only give it half a second since this is on the
2058
; installer startup path (we haven't even shown a window yet).
2059
StrCpy $6 0
2060
${Do}
2061
Sleep 100
2062
InetBgDL::GetStats
2063
IntOp $6 $6 + 1
2064
2065
${If} $2 == 0
2066
${Break}
2067
${ElseIf} $6 >= 5
2068
InetBgDL::Get /RESET /END
2069
SetErrors
2070
GoTo end
2071
${EndIf}
2072
${Loop}
2073
2074
StrCpy $1 0
2075
nsJSON::Set /file "$PLUGINSDIR\firefox_versions.json"
2076
IfErrors end
2077
${Select} ${Channel}
2078
${Case} "unofficial"
2079
StrCpy $1 "FIREFOX_NIGHTLY"
2080
${Case} "nightly"
2081
StrCpy $1 "FIREFOX_NIGHTLY"
2082
${Case} "aurora"
2083
StrCpy $1 "FIREFOX_DEVEDITION"
2084
${Case} "beta"
2085
StrCpy $1 "LATEST_FIREFOX_RELEASED_DEVEL_VERSION"
2086
${Case} "release"
2087
StrCpy $1 "LATEST_FIREFOX_VERSION"
2088
${EndSelect}
2089
nsJSON::Get $1 /end
2090
2091
end:
2092
${If} ${Errors}
2093
${OrIf} $1 == 0
2094
SetErrors
2095
StrCpy $1 0
2096
${Else}
2097
Pop $1
2098
${EndIf}
2099
2100
Pop $6
2101
Pop $5
2102
Pop $4
2103
Pop $3
2104
Pop $2
2105
Pop $0
2106
FunctionEnd
2107
2108
; Determine which architecture build we should download and install.
2109
; AArch64 is always selected if it's the native architecture of the machine.
2110
; Otherwise, we check a few things to determine if AMD64 is appropriate:
2111
; 1) Running a 64-bit OS (we've already checked the OS version).
2112
; 2) An amount of RAM strictly greater than RAM_NEEDED_FOR_64BIT
2113
; 3) No third-party products installed that cause issues with the 64-bit build.
2114
; Currently this includes Lenovo OneKey Theater and Lenovo Energy Management.
2115
; We also make sure that the partner.ini file contains a download URL for the
2116
; selected architecture, when a partner.ini file eixsts.
2117
; If any of those checks fail, the 32-bit x86 build is selected.
2118
Function GetArchToInstall
2119
StrCpy $ArchToInstall ${ARCH_X86}
2120
2121
${If} ${IsNativeARM64}
2122
StrCpy $ArchToInstall ${ARCH_AARCH64}
2123
GoTo downloadUrlCheck
2124
${EndIf}
2125
2126
${IfNot} ${IsNativeAMD64}
2127
Return
2128
${EndIf}
2129
2130
System::Call "*(i 64, i, l 0, l, l, l, l, l, l)p.r1"
2131
System::Call "Kernel32::GlobalMemoryStatusEx(p r1)"
2132
System::Call "*$1(i, i, l.r2, l, l, l, l, l, l)"
2133
System::Free $1
2134
${If} $2 L<= ${RAM_NEEDED_FOR_64BIT}
2135
Return
2136
${EndIf}
2137
2138
; Lenovo OneKey Theater can theoretically be in a directory other than this
2139
; one, because some installer versions let you change it, but it's unlikely.
2140
${If} ${FileExists} "$PROGRAMFILES32\Lenovo\Onekey Theater\windowsapihookdll64.dll"
2141
Return
2142
${EndIf}
2143
2144
${If} ${FileExists} "$PROGRAMFILES32\Lenovo\Energy Management\Energy Management.exe"
2145
Return
2146
${EndIf}
2147
2148
StrCpy $ArchToInstall ${ARCH_AMD64}
2149
2150
downloadUrlCheck:
2151
; If we've selected an architecture that doesn't have a download URL in the
2152
; partner.ini, but there is a URL there for 32-bit x86, then fall back to
2153
; 32-bit x86 on the theory that we should never use a non-partner build if
2154
; we are configured as a partner installer, even if the only build that's
2155
; provided is suboptimal for the machine. If there isn't even an x86 URL,
2156
; then we won't force x86 and GetDownloadURL will stick with the built-in URL.
2157
ClearErrors
2158
ReadINIStr $1 "${PARTNER_INI}" "DownloadURL" "X86"
2159
${IfNot} ${Errors}
2160
${If} $ArchToInstall == ${ARCH_AMD64}
2161
ReadINIStr $1 "${PARTNER_INI}" "DownloadURL" "AMD64"
2162
${If} ${Errors}
2163
StrCpy $ArchToInstall ${ARCH_X86}
2164
${EndIf}
2165
${ElseIf} $ArchToInstall == ${ARCH_AARCH64}
2166
ReadINIStr $1 "${PARTNER_INI}" "DownloadURL" "AArch64"
2167
${If} ${Errors}
2168
StrCpy $ArchToInstall ${ARCH_X86}
2169
${EndIf}
2170
${EndIf}
2171
${EndIf}
2172
FunctionEnd
2173
2174
Function GetDownloadURL
2175
Push $0
2176
Push $1
2177
2178
; Start with the appropriate URL from our built-in branding info.
2179
${If} $ArchToInstall == ${ARCH_AMD64}
2180
StrCpy $0 "${URLStubDownloadAMD64}${URLStubDownloadAppend}"
2181
${ElseIf} $ArchToInstall == ${ARCH_AARCH64}
2182
StrCpy $0 "${URLStubDownloadAArch64}${URLStubDownloadAppend}"
2183
${Else}
2184
StrCpy $0 "${URLStubDownloadX86}${URLStubDownloadAppend}"
2185
${EndIf}
2186
2187
; If we have a partner.ini file then use the URL from there instead.
2188
ClearErrors
2189
${If} $ArchToInstall == ${ARCH_AMD64}
2190
ReadINIStr $1 "${PARTNER_INI}" "DownloadURL" "AMD64"
2191
${ElseIf} $ArchToInstall == ${ARCH_AARCH64}
2192
ReadINIStr $1 "${PARTNER_INI}" "DownloadURL" "AArch64"
2193
${Else}
2194
ReadINIStr $1 "${PARTNER_INI}" "DownloadURL" "X86"
2195
${EndIf}
2196
${IfNot} ${Errors}
2197
StrCpy $0 "$1"
2198
${EndIf}
2199
2200
Pop $1
2201
Exch $0
2202
FunctionEnd
2203
2204
Section
2205
SectionEnd