summaryrefslogtreecommitdiff
path: root/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp
diff options
context:
space:
mode:
authorRob Mensching <rob@firegiant.com>2021-05-03 15:55:48 -0700
committerRob Mensching <rob@firegiant.com>2021-05-03 15:55:48 -0700
commitba7bab476501c16e437b0aee71c1be02c3dda176 (patch)
tree814fba485c29a7dfe1adb396169e27ed641ef9a3 /src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp
parent14987a72cc1a3493ca8f80693d273352fc314bd9 (diff)
downloadwix-ba7bab476501c16e437b0aee71c1be02c3dda176.tar.gz
wix-ba7bab476501c16e437b0aee71c1be02c3dda176.tar.bz2
wix-ba7bab476501c16e437b0aee71c1be02c3dda176.zip
Move Bal.wixext into ext
Diffstat (limited to 'src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp')
-rw-r--r--src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp4264
1 files changed, 4264 insertions, 0 deletions
diff --git a/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp b/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp
new file mode 100644
index 00000000..d4bf7b43
--- /dev/null
+++ b/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp
@@ -0,0 +1,4264 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3#include "precomp.h"
4#include "BalBaseBootstrapperApplicationProc.h"
5#include "BalBaseBootstrapperApplication.h"
6
7static const LPCWSTR WIXBUNDLE_VARIABLE_ELEVATED = L"WixBundleElevated";
8
9static const LPCWSTR WIXSTDBA_WINDOW_CLASS = L"WixStdBA";
10
11static const LPCWSTR WIXSTDBA_VARIABLE_INSTALL_FOLDER = L"InstallFolder";
12static const LPCWSTR WIXSTDBA_VARIABLE_LAUNCH_TARGET_PATH = L"LaunchTarget";
13static const LPCWSTR WIXSTDBA_VARIABLE_LAUNCH_TARGET_ELEVATED_ID = L"LaunchTargetElevatedId";
14static const LPCWSTR WIXSTDBA_VARIABLE_LAUNCH_ARGUMENTS = L"LaunchArguments";
15static const LPCWSTR WIXSTDBA_VARIABLE_LAUNCH_HIDDEN = L"LaunchHidden";
16static const LPCWSTR WIXSTDBA_VARIABLE_LAUNCH_WORK_FOLDER = L"LaunchWorkingFolder";
17
18static const DWORD WIXSTDBA_ACQUIRE_PERCENTAGE = 30;
19
20static const LPCWSTR WIXSTDBA_VARIABLE_BUNDLE_FILE_VERSION = L"WixBundleFileVersion";
21static const LPCWSTR WIXSTDBA_VARIABLE_LANGUAGE_ID = L"WixStdBALanguageId";
22static const LPCWSTR WIXSTDBA_VARIABLE_RESTART_REQUIRED = L"WixStdBARestartRequired";
23static const LPCWSTR WIXSTDBA_VARIABLE_SHOW_VERSION = L"WixStdBAShowVersion";
24static const LPCWSTR WIXSTDBA_VARIABLE_SUPPRESS_OPTIONS_UI = L"WixStdBASuppressOptionsUI";
25
26enum WIXSTDBA_STATE
27{
28 WIXSTDBA_STATE_INITIALIZING,
29 WIXSTDBA_STATE_INITIALIZED,
30 WIXSTDBA_STATE_HELP,
31 WIXSTDBA_STATE_DETECTING,
32 WIXSTDBA_STATE_DETECTED,
33 WIXSTDBA_STATE_PLANNING,
34 WIXSTDBA_STATE_PLANNED,
35 WIXSTDBA_STATE_APPLYING,
36 WIXSTDBA_STATE_CACHING,
37 WIXSTDBA_STATE_CACHED,
38 WIXSTDBA_STATE_EXECUTING,
39 WIXSTDBA_STATE_EXECUTED,
40 WIXSTDBA_STATE_APPLIED,
41 WIXSTDBA_STATE_FAILED,
42};
43
44enum WM_WIXSTDBA
45{
46 WM_WIXSTDBA_SHOW_HELP = WM_APP + 100,
47 WM_WIXSTDBA_DETECT_PACKAGES,
48 WM_WIXSTDBA_PLAN_PACKAGES,
49 WM_WIXSTDBA_APPLY_PACKAGES,
50 WM_WIXSTDBA_CHANGE_STATE,
51 WM_WIXSTDBA_SHOW_FAILURE,
52};
53
54// This enum must be kept in the same order as the vrgwzPageNames array.
55enum WIXSTDBA_PAGE
56{
57 WIXSTDBA_PAGE_LOADING,
58 WIXSTDBA_PAGE_HELP,
59 WIXSTDBA_PAGE_INSTALL,
60 WIXSTDBA_PAGE_MODIFY,
61 WIXSTDBA_PAGE_PROGRESS,
62 WIXSTDBA_PAGE_PROGRESS_PASSIVE,
63 WIXSTDBA_PAGE_SUCCESS,
64 WIXSTDBA_PAGE_FAILURE,
65 COUNT_WIXSTDBA_PAGE,
66};
67
68// This array must be kept in the same order as the WIXSTDBA_PAGE enum.
69static LPCWSTR vrgwzPageNames[] = {
70 L"Loading",
71 L"Help",
72 L"Install",
73 L"Modify",
74 L"Progress",
75 L"ProgressPassive",
76 L"Success",
77 L"Failure",
78};
79
80enum WIXSTDBA_CONTROL
81{
82 // Welcome page
83 WIXSTDBA_CONTROL_INSTALL_BUTTON = THEME_FIRST_ASSIGN_CONTROL_ID,
84 WIXSTDBA_CONTROL_EULA_RICHEDIT,
85 WIXSTDBA_CONTROL_EULA_LINK,
86 WIXSTDBA_CONTROL_EULA_ACCEPT_CHECKBOX,
87
88 // Modify page
89 WIXSTDBA_CONTROL_REPAIR_BUTTON,
90 WIXSTDBA_CONTROL_UNINSTALL_BUTTON,
91
92 // Progress page
93 WIXSTDBA_CONTROL_CACHE_PROGRESS_PACKAGE_TEXT,
94 WIXSTDBA_CONTROL_CACHE_PROGRESS_BAR,
95 WIXSTDBA_CONTROL_CACHE_PROGRESS_TEXT,
96
97 WIXSTDBA_CONTROL_EXECUTE_PROGRESS_PACKAGE_TEXT,
98 WIXSTDBA_CONTROL_EXECUTE_PROGRESS_BAR,
99 WIXSTDBA_CONTROL_EXECUTE_PROGRESS_TEXT,
100 WIXSTDBA_CONTROL_EXECUTE_PROGRESS_ACTIONDATA_TEXT,
101
102 WIXSTDBA_CONTROL_OVERALL_PROGRESS_PACKAGE_TEXT,
103 WIXSTDBA_CONTROL_OVERALL_PROGRESS_BAR,
104 WIXSTDBA_CONTROL_OVERALL_CALCULATED_PROGRESS_BAR,
105 WIXSTDBA_CONTROL_OVERALL_PROGRESS_TEXT,
106
107 WIXSTDBA_CONTROL_PROGRESS_CANCEL_BUTTON,
108
109 // Success page
110 WIXSTDBA_CONTROL_LAUNCH_BUTTON,
111 WIXSTDBA_CONTROL_SUCCESS_RESTART_BUTTON,
112
113 // Failure page
114 WIXSTDBA_CONTROL_FAILURE_LOGFILE_LINK,
115 WIXSTDBA_CONTROL_FAILURE_MESSAGE_TEXT,
116 WIXSTDBA_CONTROL_FAILURE_RESTART_BUTTON,
117};
118
119static THEME_ASSIGN_CONTROL_ID vrgInitControls[] = {
120 { WIXSTDBA_CONTROL_INSTALL_BUTTON, L"InstallButton" },
121 { WIXSTDBA_CONTROL_EULA_RICHEDIT, L"EulaRichedit" },
122 { WIXSTDBA_CONTROL_EULA_LINK, L"EulaHyperlink" },
123 { WIXSTDBA_CONTROL_EULA_ACCEPT_CHECKBOX, L"EulaAcceptCheckbox" },
124
125 { WIXSTDBA_CONTROL_REPAIR_BUTTON, L"RepairButton" },
126 { WIXSTDBA_CONTROL_UNINSTALL_BUTTON, L"UninstallButton" },
127
128 { WIXSTDBA_CONTROL_CACHE_PROGRESS_PACKAGE_TEXT, L"CacheProgressPackageText" },
129 { WIXSTDBA_CONTROL_CACHE_PROGRESS_BAR, L"CacheProgressbar" },
130 { WIXSTDBA_CONTROL_CACHE_PROGRESS_TEXT, L"CacheProgressText" },
131 { WIXSTDBA_CONTROL_EXECUTE_PROGRESS_PACKAGE_TEXT, L"ExecuteProgressPackageText" },
132 { WIXSTDBA_CONTROL_EXECUTE_PROGRESS_BAR, L"ExecuteProgressbar" },
133 { WIXSTDBA_CONTROL_EXECUTE_PROGRESS_TEXT, L"ExecuteProgressText" },
134 { WIXSTDBA_CONTROL_EXECUTE_PROGRESS_ACTIONDATA_TEXT, L"ExecuteProgressActionDataText"},
135 { WIXSTDBA_CONTROL_OVERALL_PROGRESS_PACKAGE_TEXT, L"OverallProgressPackageText" },
136 { WIXSTDBA_CONTROL_OVERALL_PROGRESS_BAR, L"OverallProgressbar" },
137 { WIXSTDBA_CONTROL_OVERALL_CALCULATED_PROGRESS_BAR, L"OverallCalculatedProgressbar" },
138 { WIXSTDBA_CONTROL_OVERALL_PROGRESS_TEXT, L"OverallProgressText" },
139 { WIXSTDBA_CONTROL_PROGRESS_CANCEL_BUTTON, L"ProgressCancelButton" },
140
141 { WIXSTDBA_CONTROL_LAUNCH_BUTTON, L"LaunchButton" },
142 { WIXSTDBA_CONTROL_SUCCESS_RESTART_BUTTON, L"SuccessRestartButton" },
143
144 { WIXSTDBA_CONTROL_FAILURE_LOGFILE_LINK, L"FailureLogFileLink" },
145 { WIXSTDBA_CONTROL_FAILURE_MESSAGE_TEXT, L"FailureMessageText" },
146 { WIXSTDBA_CONTROL_FAILURE_RESTART_BUTTON, L"FailureRestartButton" },
147};
148
149typedef struct _WIXSTDBA_PACKAGE_INFO
150{
151 LPWSTR sczPackageId;
152 BOOL fWasAlreadyInstalled;
153 BOOL fPlannedToBeInstalled;
154 BOOL fSuccessfullyInstalled;
155} WIXSTDBA_PACKAGE_INFO;
156
157
158static HRESULT DAPI EvaluateVariableConditionCallback(
159 __in_z LPCWSTR wzCondition,
160 __out BOOL* pf,
161 __in_opt LPVOID pvContext
162 );
163static HRESULT DAPI FormatVariableStringCallback(
164 __in_z LPCWSTR wzFormat,
165 __inout LPWSTR* psczOut,
166 __in_opt LPVOID pvContext
167 );
168static HRESULT DAPI GetVariableNumericCallback(
169 __in_z LPCWSTR wzVariable,
170 __out LONGLONG* pllValue,
171 __in_opt LPVOID pvContext
172 );
173static HRESULT DAPI SetVariableNumericCallback(
174 __in_z LPCWSTR wzVariable,
175 __in LONGLONG llValue,
176 __in_opt LPVOID pvContext
177 );
178static HRESULT DAPI GetVariableStringCallback(
179 __in_z LPCWSTR wzVariable,
180 __inout LPWSTR* psczValue,
181 __in_opt LPVOID pvContext
182 );
183static HRESULT DAPI SetVariableStringCallback(
184 __in_z LPCWSTR wzVariable,
185 __in_z_opt LPCWSTR wzValue,
186 __in BOOL fFormatted,
187 __in_opt LPVOID pvContext
188 );
189static LPCSTR LoggingRequestStateToString(
190 __in BOOTSTRAPPER_REQUEST_STATE requestState
191 );
192static LPCSTR LoggingMsiFeatureStateToString(
193 __in BOOTSTRAPPER_FEATURE_STATE featureState
194 );
195
196
197class CWixStandardBootstrapperApplication : public CBalBaseBootstrapperApplication
198{
199public: // IBootstrapperApplication
200 virtual STDMETHODIMP OnStartup()
201 {
202 HRESULT hr = S_OK;
203 DWORD dwUIThreadId = 0;
204
205 // create UI thread
206 m_hUiThread = ::CreateThread(NULL, 0, UiThreadProc, this, 0, &dwUIThreadId);
207 if (!m_hUiThread)
208 {
209 ExitWithLastError(hr, "Failed to create UI thread.");
210 }
211
212 LExit:
213 return hr;
214 }
215
216
217 virtual STDMETHODIMP OnShutdown(
218 __inout BOOTSTRAPPER_SHUTDOWN_ACTION* pAction
219 )
220 {
221 HRESULT hr = S_OK;
222
223 // wait for UI thread to terminate
224 if (m_hUiThread)
225 {
226 ::WaitForSingleObject(m_hUiThread, INFINITE);
227 ReleaseHandle(m_hUiThread);
228 }
229
230 // If a restart was required.
231 if (m_fRestartRequired)
232 {
233 if (m_fAllowRestart)
234 {
235 *pAction = BOOTSTRAPPER_SHUTDOWN_ACTION_RESTART;
236 }
237
238 if (m_fPrereq)
239 {
240 BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, m_fAllowRestart ? "The prerequisites scheduled a restart. The bootstrapper application will be reloaded after the computer is restarted."
241 : "A restart is required by the prerequisites but the user delayed it. The bootstrapper application will be reloaded after the computer is restarted.");
242 }
243 }
244 else if (m_fPrereqInstalled)
245 {
246 BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "The prerequisites were successfully installed. The bootstrapper application will be reloaded.");
247 *pAction = BOOTSTRAPPER_SHUTDOWN_ACTION_RELOAD_BOOTSTRAPPER;
248 }
249 else if (m_fPrereqAlreadyInstalled)
250 {
251 BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "The prerequisites were already installed. The bootstrapper application will not be reloaded to prevent an infinite loop.");
252 }
253 else if (m_fPrereq)
254 {
255 BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "The prerequisites were not successfully installed, error: 0x%x. The bootstrapper application will be not reloaded.", m_hrFinal);
256 }
257
258 return hr;
259 }
260
261
262 virtual STDMETHODIMP OnDetectRelatedBundle(
263 __in LPCWSTR wzBundleId,
264 __in BOOTSTRAPPER_RELATION_TYPE relationType,
265 __in LPCWSTR wzBundleTag,
266 __in BOOL fPerMachine,
267 __in LPCWSTR wzVersion,
268 __in BOOTSTRAPPER_RELATED_OPERATION operation,
269 __in BOOL fMissingFromCache,
270 __inout BOOL* pfCancel
271 )
272 {
273 BAL_INFO_PACKAGE* pPackage = NULL;
274
275 if (!fMissingFromCache)
276 {
277 if (SUCCEEDED(BalInfoAddRelatedBundleAsPackage(&m_Bundle.packages, wzBundleId, relationType, fPerMachine, &pPackage)))
278 {
279 InitializePackageInfoForPackage(pPackage);
280 }
281
282 // If we're not doing a prerequisite install, remember when our bundle would cause a downgrade.
283 if (!m_fPrereq && BOOTSTRAPPER_RELATED_OPERATION_DOWNGRADE == operation)
284 {
285 m_fDowngrading = TRUE;
286 }
287 }
288
289 return CBalBaseBootstrapperApplication::OnDetectRelatedBundle(wzBundleId, relationType, wzBundleTag, fPerMachine, wzVersion, operation, fMissingFromCache, pfCancel);
290 }
291
292
293 virtual STDMETHODIMP OnDetectPackageComplete(
294 __in LPCWSTR wzPackageId,
295 __in HRESULT /*hrStatus*/,
296 __in BOOTSTRAPPER_PACKAGE_STATE state
297 )
298 {
299 WIXSTDBA_PACKAGE_INFO* pPackageInfo = NULL;
300 BAL_INFO_PACKAGE* pPackage = NULL;
301
302 if (BOOTSTRAPPER_PACKAGE_STATE_PRESENT == state &&
303 SUCCEEDED(GetPackageInfo(wzPackageId, &pPackageInfo, &pPackage)) &&
304 pPackageInfo)
305 {
306 // If the package is already installed, remember that.
307 pPackageInfo->fWasAlreadyInstalled = TRUE;
308 }
309
310 return S_OK;
311 }
312
313
314 virtual STDMETHODIMP OnDetectComplete(
315 __in HRESULT hrStatus,
316 __in BOOL /*fEligibleForCleanup*/
317 )
318 {
319 HRESULT hr = S_OK;
320 // If we're not interacting with the user or we're doing a layout or we're resuming just after a force restart
321 // then automatically start planning.
322 BOOL fSkipToPlan = SUCCEEDED(hrStatus) &&
323 (BOOTSTRAPPER_DISPLAY_FULL > m_command.display ||
324 BOOTSTRAPPER_ACTION_LAYOUT == m_command.action ||
325 BOOTSTRAPPER_RESUME_TYPE_REBOOT == m_command.resumeType);
326 // If we're requiring user input (which currently means Install, Repair, or Uninstall)
327 // or if we're skipping to an action that modifies machine state
328 // then evaluate conditions.
329 BOOL fEvaluateConditions = SUCCEEDED(hrStatus) &&
330 (!fSkipToPlan || BOOTSTRAPPER_ACTION_LAYOUT < m_command.action && BOOTSTRAPPER_ACTION_UPDATE_REPLACE > m_command.action);
331
332 if (fEvaluateConditions)
333 {
334 hrStatus = EvaluateConditions();
335 }
336
337 if (FAILED(hrStatus))
338 {
339 fSkipToPlan = FALSE;
340 }
341 else
342 {
343 if (m_fPrereq)
344 {
345 m_fPrereqAlreadyInstalled = TRUE;
346
347 // At this point we have to assume that all prerequisite packages need to be installed, so set to false if any of them aren't installed.
348 for (DWORD i = 0; i < m_Bundle.packages.cPackages; ++i)
349 {
350 BAL_INFO_PACKAGE* pPackage = &m_Bundle.packages.rgPackages[i];
351 WIXSTDBA_PACKAGE_INFO* pPackageInfo = reinterpret_cast<WIXSTDBA_PACKAGE_INFO*>(pPackage->pvCustomData);
352 if (pPackage->fPrereqPackage && pPackageInfo && !pPackageInfo->fWasAlreadyInstalled)
353 {
354 m_fPrereqAlreadyInstalled = FALSE;
355 break;
356 }
357 }
358 }
359 }
360
361 SetState(WIXSTDBA_STATE_DETECTED, hrStatus);
362
363 if (fSkipToPlan)
364 {
365 ::PostMessageW(m_hWnd, WM_WIXSTDBA_PLAN_PACKAGES, 0, m_command.action);
366 }
367
368 return hr;
369 }
370
371
372 virtual STDMETHODIMP OnPlanRelatedBundle(
373 __in_z LPCWSTR wzBundleId,
374 __in BOOTSTRAPPER_REQUEST_STATE recommendedState,
375 __inout_z BOOTSTRAPPER_REQUEST_STATE* pRequestedState,
376 __inout BOOL* pfCancel
377 )
378 {
379 // If we're only installing prerequisites, do not touch related bundles.
380 if (m_fPrereq)
381 {
382 *pRequestedState = BOOTSTRAPPER_REQUEST_STATE_NONE;
383 }
384
385 return CBalBaseBootstrapperApplication::OnPlanRelatedBundle(wzBundleId, recommendedState, pRequestedState, pfCancel);
386 }
387
388
389 virtual STDMETHODIMP OnPlanPackageBegin(
390 __in_z LPCWSTR wzPackageId,
391 __in BOOTSTRAPPER_PACKAGE_STATE state,
392 __in BOOL fCached,
393 __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition,
394 __in BOOTSTRAPPER_REQUEST_STATE recommendedState,
395 __in BOOTSTRAPPER_CACHE_TYPE recommendedCacheType,
396 __inout BOOTSTRAPPER_REQUEST_STATE* pRequestState,
397 __inout BOOTSTRAPPER_CACHE_TYPE* pRequestedCacheType,
398 __inout BOOL* pfCancel
399 )
400 {
401 HRESULT hr = S_OK;
402 WIXSTDBA_PACKAGE_INFO* pPackageInfo = NULL;
403 BAL_INFO_PACKAGE* pPackage = NULL;
404
405 // If we're planning to install prerequisites, install them. The prerequisites need to be installed
406 // in all cases (even uninstall!) so the BA can load next.
407 if (m_fPrereq)
408 {
409 // Only install prerequisite packages, and check the InstallCondition on them.
410 BOOL fInstall = FALSE;
411 hr = GetPackageInfo(wzPackageId, &pPackageInfo, &pPackage);
412 if (SUCCEEDED(hr) && pPackage->fPrereqPackage && pPackageInfo)
413 {
414 pPackageInfo->fPlannedToBeInstalled = fInstall = BOOTSTRAPPER_PACKAGE_CONDITION_FALSE != installCondition;
415 }
416
417 if (fInstall)
418 {
419 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_PRESENT;
420 }
421 else
422 {
423 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE;
424 }
425
426 // Don't force cache packages while installing prerequisites.
427 if (BOOTSTRAPPER_CACHE_TYPE_FORCE == *pRequestedCacheType)
428 {
429 *pRequestedCacheType = BOOTSTRAPPER_CACHE_TYPE_KEEP;
430 }
431 }
432 else if (m_sczAfterForcedRestartPackage) // after force restart, skip packages until after the package that caused the restart.
433 {
434 // After restart we need to finish the dependency registration for our package so allow the package
435 // to go present.
436 if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, wzPackageId, -1, m_sczAfterForcedRestartPackage, -1))
437 {
438 // Do not allow a repair because that could put us in a perpetual restart loop.
439 if (BOOTSTRAPPER_REQUEST_STATE_REPAIR == *pRequestState)
440 {
441 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_PRESENT;
442 }
443
444 ReleaseNullStr(m_sczAfterForcedRestartPackage); // no more skipping now.
445 }
446 else // not the matching package, so skip it.
447 {
448 BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Skipping package: %ls, after restart because it was applied before the restart.", wzPackageId);
449
450 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE;
451 }
452 }
453
454 return CBalBaseBootstrapperApplication::OnPlanPackageBegin(wzPackageId, state, fCached, installCondition, recommendedState, recommendedCacheType, pRequestState, pRequestedCacheType, pfCancel);
455 }
456
457
458 virtual STDMETHODIMP OnPlanMsiPackage(
459 __in_z LPCWSTR wzPackageId,
460 __in BOOL fExecute,
461 __in BOOTSTRAPPER_ACTION_STATE action,
462 __inout BOOL* pfCancel,
463 __inout BURN_MSI_PROPERTY* pActionMsiProperty,
464 __inout INSTALLUILEVEL* pUiLevel,
465 __inout BOOL* pfDisableExternalUiHandler
466 )
467 {
468 HRESULT hr = S_OK;
469 WIXSTDBA_PACKAGE_INFO* pPackageInfo = NULL;
470 BAL_INFO_PACKAGE* pPackage = NULL;
471 BOOL fShowInternalUI = FALSE;
472 INSTALLUILEVEL uiLevel = INSTALLUILEVEL_NOCHANGE;
473
474 switch (m_command.display)
475 {
476 case BOOTSTRAPPER_DISPLAY_FULL:
477 uiLevel = INSTALLUILEVEL_FULL;
478 break;
479
480 case BOOTSTRAPPER_DISPLAY_PASSIVE:
481 uiLevel = INSTALLUILEVEL_REDUCED;
482 break;
483 }
484
485 if (INSTALLUILEVEL_NOCHANGE != uiLevel)
486 {
487 hr = GetPackageInfo(wzPackageId, &pPackageInfo, &pPackage);
488 if (SUCCEEDED(hr) && pPackage->sczDisplayInternalUICondition)
489 {
490 hr = BalEvaluateCondition(pPackage->sczDisplayInternalUICondition, &fShowInternalUI);
491 BalExitOnFailure(hr, "Failed to evaluate condition for package '%ls': %ls", wzPackageId, pPackage->sczDisplayInternalUICondition);
492
493 if (fShowInternalUI)
494 {
495 *pUiLevel = uiLevel;
496 }
497 }
498 }
499
500 LExit:
501 return __super::OnPlanMsiPackage(wzPackageId, fExecute, action, pfCancel, pActionMsiProperty, pUiLevel, pfDisableExternalUiHandler);
502 }
503
504
505 virtual STDMETHODIMP OnPlanComplete(
506 __in HRESULT hrStatus
507 )
508 {
509 HRESULT hr = S_OK;
510
511 if (m_fPrereq)
512 {
513 m_fPrereqAlreadyInstalled = TRUE;
514
515 // Now that we've planned the packages, we can focus on the prerequisite packages that are supposed to be installed.
516 for (DWORD i = 0; i < m_Bundle.packages.cPackages; ++i)
517 {
518 BAL_INFO_PACKAGE* pPackage = &m_Bundle.packages.rgPackages[i];
519 WIXSTDBA_PACKAGE_INFO* pPackageInfo = reinterpret_cast<WIXSTDBA_PACKAGE_INFO*>(pPackage->pvCustomData);
520 if (pPackage->fPrereqPackage && pPackageInfo && !pPackageInfo->fWasAlreadyInstalled && pPackageInfo->fPlannedToBeInstalled)
521 {
522 m_fPrereqAlreadyInstalled = FALSE;
523 break;
524 }
525 }
526 }
527
528 SetState(WIXSTDBA_STATE_PLANNED, hrStatus);
529
530 if (SUCCEEDED(hrStatus))
531 {
532 ::PostMessageW(m_hWnd, WM_WIXSTDBA_APPLY_PACKAGES, 0, 0);
533 }
534
535 m_fStartedExecution = FALSE;
536 m_dwCalculatedCacheProgress = 0;
537 m_dwCalculatedExecuteProgress = 0;
538
539 return hr;
540 }
541
542
543 virtual STDMETHODIMP OnPauseAutomaticUpdatesBegin(
544 )
545 {
546 HRESULT hr = S_OK;
547 LOC_STRING* pLocString = NULL;
548 LPWSTR sczFormattedString = NULL;
549 LPCWSTR wz = NULL;
550
551 hr = __super::OnPauseAutomaticUpdatesBegin();
552
553 LocGetString(m_pWixLoc, L"#(loc.PauseAutomaticUpdatesMessage)", &pLocString);
554
555 if (pLocString)
556 {
557 BalFormatString(pLocString->wzText, &sczFormattedString);
558 }
559
560 wz = sczFormattedString ? sczFormattedString : L"Pausing Windows automatic updates";
561
562 ThemeSetTextControl(m_pTheme, WIXSTDBA_CONTROL_OVERALL_PROGRESS_PACKAGE_TEXT, wz);
563
564 ReleaseStr(sczFormattedString);
565 return hr;
566 }
567
568
569 virtual STDMETHODIMP OnSystemRestorePointBegin(
570 )
571 {
572 HRESULT hr = S_OK;
573 LOC_STRING* pLocString = NULL;
574 LPWSTR sczFormattedString = NULL;
575 LPCWSTR wz = NULL;
576
577 hr = __super::OnSystemRestorePointBegin();
578
579 LocGetString(m_pWixLoc, L"#(loc.SystemRestorePointMessage)", &pLocString);
580
581 if (pLocString)
582 {
583 BalFormatString(pLocString->wzText, &sczFormattedString);
584 }
585
586 wz = sczFormattedString ? sczFormattedString : L"Creating system restore point";
587
588 ThemeSetTextControl(m_pTheme, WIXSTDBA_CONTROL_OVERALL_PROGRESS_PACKAGE_TEXT, wz);
589
590 ReleaseStr(sczFormattedString);
591 return hr;
592 }
593
594
595 virtual STDMETHODIMP OnCachePackageBegin(
596 __in_z LPCWSTR wzPackageId,
597 __in DWORD cCachePayloads,
598 __in DWORD64 dw64PackageCacheSize,
599 __inout BOOL* pfCancel
600 )
601 {
602 if (wzPackageId && *wzPackageId)
603 {
604 BAL_INFO_PACKAGE* pPackage = NULL;
605 HRESULT hr = BalInfoFindPackageById(&m_Bundle.packages, wzPackageId, &pPackage);
606 LPCWSTR wz = (SUCCEEDED(hr) && pPackage->sczDisplayName) ? pPackage->sczDisplayName : wzPackageId;
607
608 ThemeSetTextControl(m_pTheme, WIXSTDBA_CONTROL_CACHE_PROGRESS_PACKAGE_TEXT, wz);
609
610 // If something started executing, leave it in the overall progress text.
611 if (!m_fStartedExecution)
612 {
613 ThemeSetTextControl(m_pTheme, WIXSTDBA_CONTROL_OVERALL_PROGRESS_PACKAGE_TEXT, wz);
614 }
615 }
616
617 return __super::OnCachePackageBegin(wzPackageId, cCachePayloads, dw64PackageCacheSize, pfCancel);
618 }
619
620
621 virtual STDMETHODIMP OnCacheAcquireProgress(
622 __in_z LPCWSTR wzPackageOrContainerId,
623 __in_z_opt LPCWSTR wzPayloadId,
624 __in DWORD64 dw64Progress,
625 __in DWORD64 dw64Total,
626 __in DWORD dwOverallPercentage,
627 __inout BOOL* pfCancel
628 )
629 {
630#ifdef DEBUG
631 BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "WIXSTDBA: OnCacheAcquireProgress() - container/package: %ls, payload: %ls, progress: %I64u, total: %I64u, overall progress: %u%%", wzPackageOrContainerId, wzPayloadId, dw64Progress, dw64Total, dwOverallPercentage);
632#endif
633
634 UpdateCacheProgress(dwOverallPercentage);
635
636 return __super::OnCacheAcquireProgress(wzPackageOrContainerId, wzPayloadId, dw64Progress, dw64Total, dwOverallPercentage, pfCancel);
637 }
638
639
640 virtual STDMETHODIMP OnCacheContainerOrPayloadVerifyProgress(
641 __in_z LPCWSTR wzPackageOrContainerId,
642 __in_z_opt LPCWSTR wzPayloadId,
643 __in DWORD64 dw64Progress,
644 __in DWORD64 dw64Total,
645 __in DWORD dwOverallPercentage,
646 __inout BOOL* pfCancel
647 )
648 {
649#ifdef DEBUG
650 BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "WIXSTDBA: OnCacheContainerOrPayloadVerifyProgress() - container/package: %ls, payload: %ls, progress: %I64u, total: %I64u, overall progress: %u%%", wzPackageOrContainerId, wzPayloadId, dw64Progress, dw64Total, dwOverallPercentage);
651#endif
652
653 UpdateCacheProgress(dwOverallPercentage);
654
655 return __super::OnCacheContainerOrPayloadVerifyProgress(wzPackageOrContainerId, wzPayloadId, dw64Progress, dw64Total, dwOverallPercentage, pfCancel);
656 }
657
658
659 virtual STDMETHODIMP OnCachePayloadExtractProgress(
660 __in_z LPCWSTR wzPackageOrContainerId,
661 __in_z_opt LPCWSTR wzPayloadId,
662 __in DWORD64 dw64Progress,
663 __in DWORD64 dw64Total,
664 __in DWORD dwOverallPercentage,
665 __inout BOOL* pfCancel
666 )
667 {
668#ifdef DEBUG
669 BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "WIXSTDBA: OnCachePayloadExtractProgress() - container/package: %ls, payload: %ls, progress: %I64u, total: %I64u, overall progress: %u%%", wzPackageOrContainerId, wzPayloadId, dw64Progress, dw64Total, dwOverallPercentage);
670#endif
671
672 UpdateCacheProgress(dwOverallPercentage);
673
674 return __super::OnCachePayloadExtractProgress(wzPackageOrContainerId, wzPayloadId, dw64Progress, dw64Total, dwOverallPercentage, pfCancel);
675 }
676
677
678 virtual STDMETHODIMP OnCacheVerifyProgress(
679 __in_z LPCWSTR wzPackageOrContainerId,
680 __in_z_opt LPCWSTR wzPayloadId,
681 __in DWORD64 dw64Progress,
682 __in DWORD64 dw64Total,
683 __in DWORD dwOverallPercentage,
684 __in BOOTSTRAPPER_CACHE_VERIFY_STEP verifyStep,
685 __inout BOOL* pfCancel
686 )
687 {
688#ifdef DEBUG
689 BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "WIXSTDBA: OnCacheVerifyProgress() - container/package: %ls, payload: %ls, progress: %I64u, total: %I64u, overall progress: %u%%, step: %u", wzPackageOrContainerId, wzPayloadId, dw64Progress, dw64Total, dwOverallPercentage, verifyStep);
690#endif
691
692 UpdateCacheProgress(dwOverallPercentage);
693
694 return __super::OnCacheVerifyProgress(wzPackageOrContainerId, wzPayloadId, dw64Progress, dw64Total, dwOverallPercentage, verifyStep, pfCancel);
695 }
696
697
698 virtual STDMETHODIMP OnCacheAcquireComplete(
699 __in_z LPCWSTR wzPackageOrContainerId,
700 __in_z_opt LPCWSTR wzPayloadId,
701 __in HRESULT hrStatus,
702 __in BOOTSTRAPPER_CACHEACQUIRECOMPLETE_ACTION recommendation,
703 __inout BOOTSTRAPPER_CACHEACQUIRECOMPLETE_ACTION* pAction
704 )
705 {
706 SetProgressState(hrStatus);
707 return __super::OnCacheAcquireComplete(wzPackageOrContainerId, wzPayloadId, hrStatus, recommendation, pAction);
708 }
709
710
711 virtual STDMETHODIMP OnCacheContainerOrPayloadVerifyComplete(
712 __in_z LPCWSTR wzPackageOrContainerId,
713 __in_z_opt LPCWSTR wzPayloadId,
714 __in HRESULT hrStatus
715 )
716 {
717 SetProgressState(hrStatus);
718 return __super::OnCacheContainerOrPayloadVerifyComplete(wzPackageOrContainerId, wzPayloadId, hrStatus);
719 }
720
721
722 virtual STDMETHODIMP OnCachePayloadExtractComplete(
723 __in_z LPCWSTR wzPackageOrContainerId,
724 __in_z_opt LPCWSTR wzPayloadId,
725 __in HRESULT hrStatus
726 )
727 {
728 SetProgressState(hrStatus);
729 return __super::OnCachePayloadExtractComplete(wzPackageOrContainerId, wzPayloadId, hrStatus);
730 }
731
732
733 virtual STDMETHODIMP OnCacheVerifyComplete(
734 __in_z LPCWSTR wzPackageId,
735 __in_z LPCWSTR wzPayloadId,
736 __in HRESULT hrStatus,
737 __in BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION recommendation,
738 __inout BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION* pAction
739 )
740 {
741 SetProgressState(hrStatus);
742 return __super::OnCacheVerifyComplete(wzPackageId, wzPayloadId, hrStatus, recommendation, pAction);
743 }
744
745
746 virtual STDMETHODIMP OnCacheComplete(
747 __in HRESULT hrStatus
748 )
749 {
750 UpdateCacheProgress(SUCCEEDED(hrStatus) ? 100 : 0);
751 ThemeSetTextControl(m_pTheme, WIXSTDBA_CONTROL_CACHE_PROGRESS_PACKAGE_TEXT, L"");
752 SetState(WIXSTDBA_STATE_CACHED, S_OK); // we always return success here and let OnApplyComplete() deal with the error.
753 return __super::OnCacheComplete(hrStatus);
754 }
755
756
757 virtual STDMETHODIMP OnError(
758 __in BOOTSTRAPPER_ERROR_TYPE errorType,
759 __in LPCWSTR wzPackageId,
760 __in DWORD dwCode,
761 __in_z LPCWSTR wzError,
762 __in DWORD dwUIHint,
763 __in DWORD /*cData*/,
764 __in_ecount_z_opt(cData) LPCWSTR* /*rgwzData*/,
765 __in int /*nRecommendation*/,
766 __inout int* pResult
767 )
768 {
769 HRESULT hr = S_OK;
770 int nResult = *pResult;
771 LPWSTR sczError = NULL;
772
773 if (BOOTSTRAPPER_DISPLAY_EMBEDDED == m_command.display)
774 {
775 hr = m_pEngine->SendEmbeddedError(dwCode, wzError, dwUIHint, &nResult);
776 if (FAILED(hr))
777 {
778 nResult = IDERROR;
779 }
780 }
781 else if (BOOTSTRAPPER_DISPLAY_FULL == m_command.display)
782 {
783 // If this is an authentication failure, let the engine try to handle it for us.
784 if (BOOTSTRAPPER_ERROR_TYPE_HTTP_AUTH_SERVER == errorType || BOOTSTRAPPER_ERROR_TYPE_HTTP_AUTH_PROXY == errorType)
785 {
786 nResult = IDTRYAGAIN;
787 }
788 else // show a generic error message box.
789 {
790 BalRetryErrorOccurred(wzPackageId, dwCode);
791
792 if (!m_fShowingInternalUiThisPackage)
793 {
794 // If no error message was provided, use the error code to try and get an error message.
795 if (!wzError || !*wzError || BOOTSTRAPPER_ERROR_TYPE_WINDOWS_INSTALLER != errorType)
796 {
797 hr = StrAllocFromError(&sczError, dwCode, NULL);
798 if (FAILED(hr) || !sczError || !*sczError)
799 {
800 // special case for ERROR_FAIL_NOACTION_REBOOT: use loc string for Windows XP
801 if (ERROR_FAIL_NOACTION_REBOOT == dwCode)
802 {
803 LOC_STRING* pLocString = NULL;
804 hr = LocGetString(m_pWixLoc, L"#(loc.ErrorFailNoActionReboot)", &pLocString);
805 if (SUCCEEDED(hr))
806 {
807 StrAllocString(&sczError, pLocString->wzText, 0);
808 }
809 else
810 {
811 StrAllocFormatted(&sczError, L"0x%x", dwCode);
812 }
813 }
814 else
815 {
816 StrAllocFormatted(&sczError, L"0x%x", dwCode);
817 }
818 }
819 hr = S_OK;
820 }
821
822 nResult = ::MessageBoxW(m_hWnd, sczError ? sczError : wzError, m_pTheme->sczCaption, dwUIHint);
823 }
824 }
825
826 SetProgressState(HRESULT_FROM_WIN32(dwCode));
827 }
828 else // just take note of the error code and let things continue.
829 {
830 BalRetryErrorOccurred(wzPackageId, dwCode);
831 }
832
833 ReleaseStr(sczError);
834 *pResult = nResult;
835 return hr;
836 }
837
838
839 virtual STDMETHODIMP OnExecuteMsiMessage(
840 __in_z LPCWSTR wzPackageId,
841 __in INSTALLMESSAGE messageType,
842 __in DWORD dwUIHint,
843 __in_z LPCWSTR wzMessage,
844 __in DWORD cData,
845 __in_ecount_z_opt(cData) LPCWSTR* rgwzData,
846 __in int nRecommendation,
847 __inout int* pResult
848 )
849 {
850#ifdef DEBUG
851 BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "WIXSTDBA: OnExecuteMsiMessage() - package: %ls, message: %ls", wzPackageId, wzMessage);
852#endif
853 if (BOOTSTRAPPER_DISPLAY_FULL == m_command.display && (INSTALLMESSAGE_WARNING == messageType || INSTALLMESSAGE_USER == messageType))
854 {
855 if (!m_fShowingInternalUiThisPackage)
856 {
857 int nResult = ::MessageBoxW(m_hWnd, wzMessage, m_pTheme->sczCaption, dwUIHint);
858 return nResult;
859 }
860 }
861
862 if (INSTALLMESSAGE_ACTIONSTART == messageType)
863 {
864 ThemeSetTextControl(m_pTheme, WIXSTDBA_CONTROL_EXECUTE_PROGRESS_ACTIONDATA_TEXT, wzMessage);
865 }
866
867 return __super::OnExecuteMsiMessage(wzPackageId, messageType, dwUIHint, wzMessage, cData, rgwzData, nRecommendation, pResult);
868 }
869
870
871 virtual STDMETHODIMP OnProgress(
872 __in DWORD dwProgressPercentage,
873 __in DWORD dwOverallProgressPercentage,
874 __inout BOOL* pfCancel
875 )
876 {
877 WCHAR wzProgress[5] = { };
878
879#ifdef DEBUG
880 BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "WIXSTDBA: OnProgress() - progress: %u%%, overall progress: %u%%", dwProgressPercentage, dwOverallProgressPercentage);
881#endif
882
883 ::StringCchPrintfW(wzProgress, countof(wzProgress), L"%u%%", dwOverallProgressPercentage);
884 ThemeSetTextControl(m_pTheme, WIXSTDBA_CONTROL_OVERALL_PROGRESS_TEXT, wzProgress);
885
886 ThemeSetProgressControl(m_pTheme, WIXSTDBA_CONTROL_OVERALL_PROGRESS_BAR, dwOverallProgressPercentage);
887 SetTaskbarButtonProgress(dwOverallProgressPercentage);
888
889 return __super::OnProgress(dwProgressPercentage, dwOverallProgressPercentage, pfCancel);
890 }
891
892
893 virtual STDMETHODIMP OnExecutePackageBegin(
894 __in_z LPCWSTR wzPackageId,
895 __in BOOL fExecute,
896 __in BOOTSTRAPPER_ACTION_STATE action,
897 __in INSTALLUILEVEL uiLevel,
898 __in BOOL fDisableExternalUiHandler,
899 __inout BOOL* pfCancel
900 )
901 {
902 HRESULT hr = S_OK;
903 LPWSTR sczFormattedString = NULL;
904 BOOL fShowingInternalUiThisPackage = FALSE;
905
906 m_fStartedExecution = TRUE;
907
908 if (wzPackageId && *wzPackageId)
909 {
910 BAL_INFO_PACKAGE* pPackage = NULL;
911 BalInfoFindPackageById(&m_Bundle.packages, wzPackageId, &pPackage);
912
913 LPCWSTR wz = wzPackageId;
914 if (pPackage)
915 {
916 LOC_STRING* pLocString = NULL;
917
918 switch (pPackage->type)
919 {
920 case BAL_INFO_PACKAGE_TYPE_BUNDLE_ADDON:
921 LocGetString(m_pWixLoc, L"#(loc.ExecuteAddonRelatedBundleMessage)", &pLocString);
922 break;
923
924 case BAL_INFO_PACKAGE_TYPE_BUNDLE_PATCH:
925 LocGetString(m_pWixLoc, L"#(loc.ExecutePatchRelatedBundleMessage)", &pLocString);
926 break;
927
928 case BAL_INFO_PACKAGE_TYPE_BUNDLE_UPGRADE:
929 LocGetString(m_pWixLoc, L"#(loc.ExecuteUpgradeRelatedBundleMessage)", &pLocString);
930 break;
931 }
932
933 if (pLocString)
934 {
935 // If the wix developer is showing a hidden variable in the UI, then obviously they don't care about keeping it safe
936 // so don't go down the rabbit hole of making sure that this is securely freed.
937 BalFormatString(pLocString->wzText, &sczFormattedString);
938 }
939
940 wz = sczFormattedString ? sczFormattedString : pPackage->sczDisplayName ? pPackage->sczDisplayName : wzPackageId;
941 }
942
943 fShowingInternalUiThisPackage = INSTALLUILEVEL_NONE != (INSTALLUILEVEL_NONE & uiLevel);
944
945 ThemeSetTextControl(m_pTheme, WIXSTDBA_CONTROL_EXECUTE_PROGRESS_PACKAGE_TEXT, wz);
946 ThemeSetTextControl(m_pTheme, WIXSTDBA_CONTROL_OVERALL_PROGRESS_PACKAGE_TEXT, wz);
947 }
948
949 ::EnterCriticalSection(&m_csShowingInternalUiThisPackage);
950 m_fShowingInternalUiThisPackage = fShowingInternalUiThisPackage;
951 hr = __super::OnExecutePackageBegin(wzPackageId, fExecute, action, uiLevel, fDisableExternalUiHandler, pfCancel);
952 ::LeaveCriticalSection(&m_csShowingInternalUiThisPackage);
953
954 ReleaseStr(sczFormattedString);
955 return hr;
956 }
957
958
959 virtual STDMETHODIMP OnExecuteProgress(
960 __in_z LPCWSTR wzPackageId,
961 __in DWORD dwProgressPercentage,
962 __in DWORD dwOverallProgressPercentage,
963 __inout BOOL* pfCancel
964 )
965 {
966 WCHAR wzProgress[5] = { };
967
968#ifdef DEBUG
969 BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "WIXSTDBA: OnExecuteProgress() - package: %ls, progress: %u%%, overall progress: %u%%", wzPackageId, dwProgressPercentage, dwOverallProgressPercentage);
970#endif
971
972 ::StringCchPrintfW(wzProgress, countof(wzProgress), L"%u%%", dwOverallProgressPercentage);
973 ThemeSetTextControl(m_pTheme, WIXSTDBA_CONTROL_EXECUTE_PROGRESS_TEXT, wzProgress);
974
975 ThemeSetProgressControl(m_pTheme, WIXSTDBA_CONTROL_EXECUTE_PROGRESS_BAR, dwOverallProgressPercentage);
976
977 m_dwCalculatedExecuteProgress = dwOverallProgressPercentage * (100 - WIXSTDBA_ACQUIRE_PERCENTAGE) / 100;
978 ThemeSetProgressControl(m_pTheme, WIXSTDBA_CONTROL_OVERALL_CALCULATED_PROGRESS_BAR, m_dwCalculatedCacheProgress + m_dwCalculatedExecuteProgress);
979
980 SetTaskbarButtonProgress(m_dwCalculatedCacheProgress + m_dwCalculatedExecuteProgress);
981
982 return __super::OnExecuteProgress(wzPackageId, dwProgressPercentage, dwOverallProgressPercentage, pfCancel);
983 }
984
985
986 virtual STDMETHODIMP OnExecutePackageComplete(
987 __in_z LPCWSTR wzPackageId,
988 __in HRESULT hrStatus,
989 __in BOOTSTRAPPER_APPLY_RESTART restart,
990 __in BOOTSTRAPPER_EXECUTEPACKAGECOMPLETE_ACTION recommendation,
991 __inout BOOTSTRAPPER_EXECUTEPACKAGECOMPLETE_ACTION* pAction
992 )
993 {
994 HRESULT hr = S_OK;
995 SetProgressState(hrStatus);
996
997 hr = __super::OnExecutePackageComplete(wzPackageId, hrStatus, restart, recommendation, pAction);
998
999 WIXSTDBA_PACKAGE_INFO* pPackageInfo = NULL;
1000 BAL_INFO_PACKAGE* pPackage;
1001 HRESULT hrPrereq = GetPackageInfo(wzPackageId, &pPackageInfo, &pPackage);
1002 if (SUCCEEDED(hrPrereq) && pPackageInfo)
1003 {
1004 pPackageInfo->fSuccessfullyInstalled = SUCCEEDED(hrStatus);
1005
1006 // If the prerequisite required a restart (any restart) then do an immediate
1007 // restart to ensure that the bundle will get launched again post reboot.
1008 if (m_fPrereq && pPackage->fPrereqPackage && BOOTSTRAPPER_APPLY_RESTART_NONE != restart)
1009 {
1010 *pAction = BOOTSTRAPPER_EXECUTEPACKAGECOMPLETE_ACTION_RESTART;
1011 }
1012 }
1013
1014 return hr;
1015 }
1016
1017
1018 virtual STDMETHODIMP OnExecuteComplete(
1019 __in HRESULT hrStatus
1020 )
1021 {
1022 HRESULT hr = S_OK;
1023
1024 ThemeSetTextControl(m_pTheme, WIXSTDBA_CONTROL_EXECUTE_PROGRESS_PACKAGE_TEXT, L"");
1025 ThemeSetTextControl(m_pTheme, WIXSTDBA_CONTROL_EXECUTE_PROGRESS_ACTIONDATA_TEXT, L"");
1026 ThemeSetTextControl(m_pTheme, WIXSTDBA_CONTROL_OVERALL_PROGRESS_PACKAGE_TEXT, L"");
1027 ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_PROGRESS_CANCEL_BUTTON, FALSE); // no more cancel.
1028 m_fShowingInternalUiThisPackage = FALSE;
1029
1030 SetState(WIXSTDBA_STATE_EXECUTED, S_OK); // we always return success here and let OnApplyComplete() deal with the error.
1031 SetProgressState(hrStatus);
1032
1033 return hr;
1034 }
1035
1036
1037 virtual STDMETHODIMP OnCacheAcquireResolving(
1038 __in_z_opt LPCWSTR wzPackageOrContainerId,
1039 __in_z_opt LPCWSTR wzPayloadId,
1040 __in_z LPCWSTR* rgSearchPaths,
1041 __in DWORD /*cSearchPaths*/,
1042 __in BOOL /*fFoundLocal*/,
1043 __in DWORD dwRecommendedSearchPath,
1044 __in_z_opt LPCWSTR /*wzDownloadUrl*/,
1045 __in_z_opt LPCWSTR /*wzPayloadContainerId*/,
1046 __in BOOTSTRAPPER_CACHE_RESOLVE_OPERATION /*recommendation*/,
1047 __inout DWORD* /*pdwChosenSearchPath*/,
1048 __inout BOOTSTRAPPER_CACHE_RESOLVE_OPERATION* pAction,
1049 __inout BOOL* pfCancel
1050 )
1051 {
1052 HRESULT hr = S_OK;
1053
1054 if (BOOTSTRAPPER_CACHE_RESOLVE_NONE == *pAction && BOOTSTRAPPER_DISPLAY_FULL == m_command.display) // prompt to change the source location.
1055 {
1056 OPENFILENAMEW ofn = { };
1057 WCHAR wzFile[MAX_PATH] = { };
1058
1059 ::StringCchCopyW(wzFile, countof(wzFile), rgSearchPaths[dwRecommendedSearchPath]);
1060
1061 ofn.lStructSize = sizeof(ofn);
1062 ofn.hwndOwner = m_hWnd;
1063 ofn.lpstrFile = wzFile;
1064 ofn.nMaxFile = countof(wzFile);
1065 ofn.lpstrFilter = L"All Files\0*.*\0";
1066 ofn.nFilterIndex = 1;
1067 ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
1068 ofn.lpstrTitle = m_pTheme->sczCaption;
1069
1070 if (::GetOpenFileNameW(&ofn))
1071 {
1072 hr = m_pEngine->SetLocalSource(wzPackageOrContainerId, wzPayloadId, ofn.lpstrFile);
1073 *pAction = BOOTSTRAPPER_CACHE_RESOLVE_RETRY;
1074 }
1075 else
1076 {
1077 *pfCancel = TRUE;
1078 }
1079 }
1080 // else there's nothing more we can do in non-interactive mode
1081
1082 *pfCancel |= CheckCanceled();
1083 return hr;
1084 }
1085
1086
1087 virtual STDMETHODIMP OnApplyComplete(
1088 __in HRESULT hrStatus,
1089 __in BOOTSTRAPPER_APPLY_RESTART restart,
1090 __in BOOTSTRAPPER_APPLYCOMPLETE_ACTION recommendation,
1091 __inout BOOTSTRAPPER_APPLYCOMPLETE_ACTION* pAction
1092 )
1093 {
1094 HRESULT hr = S_OK;
1095
1096 __super::OnApplyComplete(hrStatus, restart, recommendation, pAction);
1097
1098 m_restartResult = restart; // remember the restart result so we return the correct error code no matter what the user chooses to do in the UI.
1099
1100 // If a restart was encountered and we are not suppressing restarts, then restart is required.
1101 m_fRestartRequired = (BOOTSTRAPPER_APPLY_RESTART_NONE != restart && BOOTSTRAPPER_RESTART_NEVER < m_command.restart);
1102 BalSetStringVariable(WIXSTDBA_VARIABLE_RESTART_REQUIRED, m_fRestartRequired ? L"1" : NULL, FALSE);
1103
1104 // If a restart is required and we're not displaying a UI or we are not supposed to prompt for restart then allow the restart.
1105 m_fAllowRestart = m_fRestartRequired && (BOOTSTRAPPER_DISPLAY_FULL > m_command.display || BOOTSTRAPPER_RESTART_PROMPT < m_command.restart);
1106
1107 if (m_fPrereq)
1108 {
1109 m_fPrereqInstalled = TRUE;
1110 BOOL fInstalledAPackage = FALSE;
1111
1112 for (DWORD i = 0; i < m_Bundle.packages.cPackages; ++i)
1113 {
1114 BAL_INFO_PACKAGE* pPackage = &m_Bundle.packages.rgPackages[i];
1115 WIXSTDBA_PACKAGE_INFO* pPackageInfo = reinterpret_cast<WIXSTDBA_PACKAGE_INFO*>(pPackage->pvCustomData);
1116 if (pPackage->fPrereqPackage && pPackageInfo && pPackageInfo->fPlannedToBeInstalled && !pPackageInfo->fWasAlreadyInstalled)
1117 {
1118 if (pPackageInfo->fSuccessfullyInstalled)
1119 {
1120 fInstalledAPackage = TRUE;
1121 }
1122 else
1123 {
1124 m_fPrereqInstalled = FALSE;
1125 break;
1126 }
1127 }
1128 }
1129
1130 m_fPrereqInstalled = m_fPrereqInstalled && fInstalledAPackage;
1131 }
1132
1133 // If we are showing UI, wait a beat before moving to the final screen.
1134 if (BOOTSTRAPPER_DISPLAY_NONE < m_command.display)
1135 {
1136 ::Sleep(250);
1137 }
1138
1139 SetState(WIXSTDBA_STATE_APPLIED, hrStatus);
1140 SetTaskbarButtonProgress(100); // show full progress bar, green, yellow, or red
1141
1142 *pAction = BOOTSTRAPPER_APPLYCOMPLETE_ACTION_NONE;
1143
1144 return hr;
1145 }
1146
1147 virtual STDMETHODIMP OnLaunchApprovedExeComplete(
1148 __in HRESULT hrStatus,
1149 __in DWORD /*processId*/
1150 )
1151 {
1152 HRESULT hr = S_OK;
1153
1154 if (HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED) == hrStatus)
1155 {
1156 //try with ShelExec next time
1157 OnClickLaunchButton();
1158 }
1159 else
1160 {
1161 ::PostMessageW(m_hWnd, WM_CLOSE, 0, 0);
1162 }
1163
1164 return hr;
1165 }
1166
1167 virtual STDMETHODIMP_(void) BAProcFallback(
1168 __in BOOTSTRAPPER_APPLICATION_MESSAGE message,
1169 __in const LPVOID pvArgs,
1170 __inout LPVOID pvResults,
1171 __inout HRESULT* phr,
1172 __in_opt LPVOID /*pvContext*/
1173 )
1174 {
1175 if (!m_pfnBAFunctionsProc || FAILED(*phr))
1176 {
1177 return;
1178 }
1179
1180 // Always log before and after so we don't get blamed when BAFunctions changes something.
1181 switch (message)
1182 {
1183 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTBEGIN:
1184 OnDetectBeginFallback(reinterpret_cast<BA_ONDETECTBEGIN_ARGS*>(pvArgs), reinterpret_cast<BA_ONDETECTBEGIN_RESULTS*>(pvResults));
1185 break;
1186 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTCOMPLETE:
1187 OnDetectCompleteFallback(reinterpret_cast<BA_ONDETECTCOMPLETE_ARGS*>(pvArgs), reinterpret_cast<BA_ONDETECTCOMPLETE_RESULTS*>(pvResults));
1188 break;
1189 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANBEGIN:
1190 OnPlanBeginFallback(reinterpret_cast<BA_ONPLANBEGIN_ARGS*>(pvArgs), reinterpret_cast<BA_ONPLANBEGIN_RESULTS*>(pvResults));
1191 break;
1192 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANCOMPLETE:
1193 OnPlanCompleteFallback(reinterpret_cast<BA_ONPLANCOMPLETE_ARGS*>(pvArgs), reinterpret_cast<BA_ONPLANCOMPLETE_RESULTS*>(pvResults));
1194 break;
1195 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONSTARTUP: // BAFunctions is loaded during this event on a separate thread so it's not possible to forward it.
1196 break;
1197 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONSHUTDOWN:
1198 OnShutdownFallback(reinterpret_cast<BA_ONSHUTDOWN_ARGS*>(pvArgs), reinterpret_cast<BA_ONSHUTDOWN_RESULTS*>(pvResults));
1199 break;
1200 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONSYSTEMSHUTDOWN:
1201 OnSystemShutdownFallback(reinterpret_cast<BA_ONSYSTEMSHUTDOWN_ARGS*>(pvArgs), reinterpret_cast<BA_ONSYSTEMSHUTDOWN_RESULTS*>(pvResults));
1202 break;
1203 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTFORWARDCOMPATIBLEBUNDLE:
1204 OnDetectForwardCompatibleBundleFallback(reinterpret_cast<BA_ONDETECTFORWARDCOMPATIBLEBUNDLE_ARGS*>(pvArgs), reinterpret_cast<BA_ONDETECTFORWARDCOMPATIBLEBUNDLE_RESULTS*>(pvResults));
1205 break;
1206 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTUPDATEBEGIN:
1207 OnDetectUpdateBeginFallback(reinterpret_cast<BA_ONDETECTUPDATEBEGIN_ARGS*>(pvArgs), reinterpret_cast<BA_ONDETECTUPDATEBEGIN_RESULTS*>(pvResults));
1208 break;
1209 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTUPDATE:
1210 OnDetectUpdateFallback(reinterpret_cast<BA_ONDETECTUPDATE_ARGS*>(pvArgs), reinterpret_cast<BA_ONDETECTUPDATE_RESULTS*>(pvResults));
1211 break;
1212 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTUPDATECOMPLETE:
1213 OnDetectUpdateCompleteFallback(reinterpret_cast<BA_ONDETECTUPDATECOMPLETE_ARGS*>(pvArgs), reinterpret_cast<BA_ONDETECTUPDATECOMPLETE_RESULTS*>(pvResults));
1214 break;
1215 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTRELATEDBUNDLE:
1216 OnDetectRelatedBundleFallback(reinterpret_cast<BA_ONDETECTRELATEDBUNDLE_ARGS*>(pvArgs), reinterpret_cast<BA_ONDETECTRELATEDBUNDLE_RESULTS*>(pvResults));
1217 break;
1218 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTPACKAGEBEGIN:
1219 OnDetectPackageBeginFallback(reinterpret_cast<BA_ONDETECTPACKAGEBEGIN_ARGS*>(pvArgs), reinterpret_cast<BA_ONDETECTPACKAGEBEGIN_RESULTS*>(pvResults));
1220 break;
1221 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTRELATEDMSIPACKAGE:
1222 OnDetectRelatedMsiPackageFallback(reinterpret_cast<BA_ONDETECTRELATEDMSIPACKAGE_ARGS*>(pvArgs), reinterpret_cast<BA_ONDETECTRELATEDMSIPACKAGE_RESULTS*>(pvResults));
1223 break;
1224 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTPATCHTARGET:
1225 OnDetectPatchTargetFallback(reinterpret_cast<BA_ONDETECTPATCHTARGET_ARGS*>(pvArgs), reinterpret_cast<BA_ONDETECTPATCHTARGET_RESULTS*>(pvResults));
1226 break;
1227 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTMSIFEATURE:
1228 OnDetectMsiFeatureFallback(reinterpret_cast<BA_ONDETECTMSIFEATURE_ARGS*>(pvArgs), reinterpret_cast<BA_ONDETECTMSIFEATURE_RESULTS*>(pvResults));
1229 break;
1230 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTPACKAGECOMPLETE:
1231 OnDetectPackageCompleteFallback(reinterpret_cast<BA_ONDETECTPACKAGECOMPLETE_ARGS*>(pvArgs), reinterpret_cast<BA_ONDETECTPACKAGECOMPLETE_RESULTS*>(pvResults));
1232 break;
1233 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANRELATEDBUNDLE:
1234 OnPlanRelatedBundleFallback(reinterpret_cast<BA_ONPLANRELATEDBUNDLE_ARGS*>(pvArgs), reinterpret_cast<BA_ONPLANRELATEDBUNDLE_RESULTS*>(pvResults));
1235 break;
1236 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANPACKAGEBEGIN:
1237 OnPlanPackageBeginFallback(reinterpret_cast<BA_ONPLANPACKAGEBEGIN_ARGS*>(pvArgs), reinterpret_cast<BA_ONPLANPACKAGEBEGIN_RESULTS*>(pvResults));
1238 break;
1239 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANPATCHTARGET:
1240 OnPlanPatchTargetFallback(reinterpret_cast<BA_ONPLANPATCHTARGET_ARGS*>(pvArgs), reinterpret_cast<BA_ONPLANPATCHTARGET_RESULTS*>(pvResults));
1241 break;
1242 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANMSIFEATURE:
1243 OnPlanMsiFeatureFallback(reinterpret_cast<BA_ONPLANMSIFEATURE_ARGS*>(pvArgs), reinterpret_cast<BA_ONPLANMSIFEATURE_RESULTS*>(pvResults));
1244 break;
1245 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANPACKAGECOMPLETE:
1246 OnPlanPackageCompleteFallback(reinterpret_cast<BA_ONPLANPACKAGECOMPLETE_ARGS*>(pvArgs), reinterpret_cast<BA_ONPLANPACKAGECOMPLETE_RESULTS*>(pvResults));
1247 break;
1248 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONAPPLYBEGIN:
1249 OnApplyBeginFallback(reinterpret_cast<BA_ONAPPLYBEGIN_ARGS*>(pvArgs), reinterpret_cast<BA_ONAPPLYBEGIN_RESULTS*>(pvResults));
1250 break;
1251 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONELEVATEBEGIN:
1252 OnElevateBeginFallback(reinterpret_cast<BA_ONELEVATEBEGIN_ARGS*>(pvArgs), reinterpret_cast<BA_ONELEVATEBEGIN_RESULTS*>(pvResults));
1253 break;
1254 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONELEVATECOMPLETE:
1255 OnElevateCompleteFallback(reinterpret_cast<BA_ONELEVATECOMPLETE_ARGS*>(pvArgs), reinterpret_cast<BA_ONELEVATECOMPLETE_RESULTS*>(pvResults));
1256 break;
1257 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONPROGRESS:
1258 OnProgressFallback(reinterpret_cast<BA_ONPROGRESS_ARGS*>(pvArgs), reinterpret_cast<BA_ONPROGRESS_RESULTS*>(pvResults));
1259 break;
1260 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONERROR:
1261 OnErrorFallback(reinterpret_cast<BA_ONERROR_ARGS*>(pvArgs), reinterpret_cast<BA_ONERROR_RESULTS*>(pvResults));
1262 break;
1263 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONREGISTERBEGIN:
1264 OnRegisterBeginFallback(reinterpret_cast<BA_ONREGISTERBEGIN_ARGS*>(pvArgs), reinterpret_cast<BA_ONREGISTERBEGIN_RESULTS*>(pvResults));
1265 break;
1266 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONREGISTERCOMPLETE:
1267 OnRegisterCompleteFallback(reinterpret_cast<BA_ONREGISTERCOMPLETE_ARGS*>(pvArgs), reinterpret_cast<BA_ONREGISTERCOMPLETE_RESULTS*>(pvResults));
1268 break;
1269 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEBEGIN:
1270 OnCacheBeginFallback(reinterpret_cast<BA_ONCACHEBEGIN_ARGS*>(pvArgs), reinterpret_cast<BA_ONCACHEBEGIN_RESULTS*>(pvResults));
1271 break;
1272 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEPACKAGEBEGIN:
1273 OnCachePackageBeginFallback(reinterpret_cast<BA_ONCACHEPACKAGEBEGIN_ARGS*>(pvArgs), reinterpret_cast<BA_ONCACHEPACKAGEBEGIN_RESULTS*>(pvResults));
1274 break;
1275 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEACQUIREBEGIN:
1276 OnCacheAcquireBeginFallback(reinterpret_cast<BA_ONCACHEACQUIREBEGIN_ARGS*>(pvArgs), reinterpret_cast<BA_ONCACHEACQUIREBEGIN_RESULTS*>(pvResults));
1277 break;
1278 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEACQUIREPROGRESS:
1279 OnCacheAcquireProgressFallback(reinterpret_cast<BA_ONCACHEACQUIREPROGRESS_ARGS*>(pvArgs), reinterpret_cast<BA_ONCACHEACQUIREPROGRESS_RESULTS*>(pvResults));
1280 break;
1281 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEACQUIRERESOLVING:
1282 OnCacheAcquireResolvingFallback(reinterpret_cast<BA_ONCACHEACQUIRERESOLVING_ARGS*>(pvArgs), reinterpret_cast<BA_ONCACHEACQUIRERESOLVING_RESULTS*>(pvResults));
1283 break;
1284 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEACQUIRECOMPLETE:
1285 OnCacheAcquireCompleteFallback(reinterpret_cast<BA_ONCACHEACQUIRECOMPLETE_ARGS*>(pvArgs), reinterpret_cast<BA_ONCACHEACQUIRECOMPLETE_RESULTS*>(pvResults));
1286 break;
1287 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEVERIFYBEGIN:
1288 OnCacheVerifyBeginFallback(reinterpret_cast<BA_ONCACHEVERIFYBEGIN_ARGS*>(pvArgs), reinterpret_cast<BA_ONCACHEVERIFYBEGIN_RESULTS*>(pvResults));
1289 break;
1290 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEVERIFYCOMPLETE:
1291 OnCacheVerifyCompleteFallback(reinterpret_cast<BA_ONCACHEVERIFYCOMPLETE_ARGS*>(pvArgs), reinterpret_cast<BA_ONCACHEVERIFYCOMPLETE_RESULTS*>(pvResults));
1292 break;
1293 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEPACKAGECOMPLETE:
1294 OnCachePackageCompleteFallback(reinterpret_cast<BA_ONCACHEPACKAGECOMPLETE_ARGS*>(pvArgs), reinterpret_cast<BA_ONCACHEPACKAGECOMPLETE_RESULTS*>(pvResults));
1295 break;
1296 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHECOMPLETE:
1297 OnCacheCompleteFallback(reinterpret_cast<BA_ONCACHECOMPLETE_ARGS*>(pvArgs), reinterpret_cast<BA_ONCACHECOMPLETE_RESULTS*>(pvResults));
1298 break;
1299 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEBEGIN:
1300 OnExecuteBeginFallback(reinterpret_cast<BA_ONEXECUTEBEGIN_ARGS*>(pvArgs), reinterpret_cast<BA_ONEXECUTEBEGIN_RESULTS*>(pvResults));
1301 break;
1302 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEPACKAGEBEGIN:
1303 OnExecutePackageBeginFallback(reinterpret_cast<BA_ONEXECUTEPACKAGEBEGIN_ARGS*>(pvArgs), reinterpret_cast<BA_ONEXECUTEPACKAGEBEGIN_RESULTS*>(pvResults));
1304 break;
1305 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEPATCHTARGET:
1306 OnExecutePatchTargetFallback(reinterpret_cast<BA_ONEXECUTEPATCHTARGET_ARGS*>(pvArgs), reinterpret_cast<BA_ONEXECUTEPATCHTARGET_RESULTS*>(pvResults));
1307 break;
1308 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEPROGRESS:
1309 OnExecuteProgressFallback(reinterpret_cast<BA_ONEXECUTEPROGRESS_ARGS*>(pvArgs), reinterpret_cast<BA_ONEXECUTEPROGRESS_RESULTS*>(pvResults));
1310 break;
1311 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEMSIMESSAGE:
1312 OnExecuteMsiMessageFallback(reinterpret_cast<BA_ONEXECUTEMSIMESSAGE_ARGS*>(pvArgs), reinterpret_cast<BA_ONEXECUTEMSIMESSAGE_RESULTS*>(pvResults));
1313 break;
1314 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEFILESINUSE:
1315 OnExecuteFilesInUseFallback(reinterpret_cast<BA_ONEXECUTEFILESINUSE_ARGS*>(pvArgs), reinterpret_cast<BA_ONEXECUTEFILESINUSE_RESULTS*>(pvResults));
1316 break;
1317 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEPACKAGECOMPLETE:
1318 OnExecutePackageCompleteFallback(reinterpret_cast<BA_ONEXECUTEPACKAGECOMPLETE_ARGS*>(pvArgs), reinterpret_cast<BA_ONEXECUTEPACKAGECOMPLETE_RESULTS*>(pvResults));
1319 break;
1320 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTECOMPLETE:
1321 OnExecuteCompleteFallback(reinterpret_cast<BA_ONEXECUTECOMPLETE_ARGS*>(pvArgs), reinterpret_cast<BA_ONEXECUTECOMPLETE_RESULTS*>(pvResults));
1322 break;
1323 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONUNREGISTERBEGIN:
1324 OnUnregisterBeginFallback(reinterpret_cast<BA_ONUNREGISTERBEGIN_ARGS*>(pvArgs), reinterpret_cast<BA_ONUNREGISTERBEGIN_RESULTS*>(pvResults));
1325 break;
1326 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONUNREGISTERCOMPLETE:
1327 OnUnregisterCompleteFallback(reinterpret_cast<BA_ONUNREGISTERCOMPLETE_ARGS*>(pvArgs), reinterpret_cast<BA_ONUNREGISTERCOMPLETE_RESULTS*>(pvResults));
1328 break;
1329 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONAPPLYCOMPLETE:
1330 OnApplyCompleteFallback(reinterpret_cast<BA_ONAPPLYCOMPLETE_ARGS*>(pvArgs), reinterpret_cast<BA_ONAPPLYCOMPLETE_RESULTS*>(pvResults));
1331 break;
1332 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONLAUNCHAPPROVEDEXEBEGIN:
1333 OnLaunchApprovedExeBeginFallback(reinterpret_cast<BA_ONLAUNCHAPPROVEDEXEBEGIN_ARGS*>(pvArgs), reinterpret_cast<BA_ONLAUNCHAPPROVEDEXEBEGIN_RESULTS*>(pvResults));
1334 break;
1335 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONLAUNCHAPPROVEDEXECOMPLETE:
1336 OnLaunchApprovedExeCompleteFallback(reinterpret_cast<BA_ONLAUNCHAPPROVEDEXECOMPLETE_ARGS*>(pvArgs), reinterpret_cast<BA_ONLAUNCHAPPROVEDEXECOMPLETE_RESULTS*>(pvResults));
1337 break;
1338 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANMSIPACKAGE:
1339 OnPlanMsiPackageFallback(reinterpret_cast<BA_ONPLANMSIPACKAGE_ARGS*>(pvArgs), reinterpret_cast<BA_ONPLANMSIPACKAGE_RESULTS*>(pvResults));
1340 break;
1341 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONBEGINMSITRANSACTIONBEGIN:
1342 OnBeginMsiTransactionBeginFallback(reinterpret_cast<BA_ONBEGINMSITRANSACTIONBEGIN_ARGS*>(pvArgs), reinterpret_cast<BA_ONBEGINMSITRANSACTIONBEGIN_RESULTS*>(pvResults));
1343 break;
1344 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONBEGINMSITRANSACTIONCOMPLETE:
1345 OnBeginMsiTransactionCompleteFallback(reinterpret_cast<BA_ONBEGINMSITRANSACTIONCOMPLETE_ARGS*>(pvArgs), reinterpret_cast<BA_ONBEGINMSITRANSACTIONCOMPLETE_RESULTS*>(pvResults));
1346 break;
1347 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONCOMMITMSITRANSACTIONBEGIN:
1348 OnCommitMsiTransactionBeginFallback(reinterpret_cast<BA_ONCOMMITMSITRANSACTIONBEGIN_ARGS*>(pvArgs), reinterpret_cast<BA_ONCOMMITMSITRANSACTIONBEGIN_RESULTS*>(pvResults));
1349 break;
1350 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONCOMMITMSITRANSACTIONCOMPLETE:
1351 OnCommitMsiTransactionCompleteFallback(reinterpret_cast<BA_ONCOMMITMSITRANSACTIONCOMPLETE_ARGS*>(pvArgs), reinterpret_cast<BA_ONCOMMITMSITRANSACTIONCOMPLETE_RESULTS*>(pvResults));
1352 break;
1353 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONROLLBACKMSITRANSACTIONBEGIN:
1354 OnRollbackMsiTransactionBeginFallback(reinterpret_cast<BA_ONROLLBACKMSITRANSACTIONBEGIN_ARGS*>(pvArgs), reinterpret_cast<BA_ONROLLBACKMSITRANSACTIONBEGIN_RESULTS*>(pvResults));
1355 break;
1356 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONROLLBACKMSITRANSACTIONCOMPLETE:
1357 OnRollbackMsiTransactionCompleteFallback(reinterpret_cast<BA_ONROLLBACKMSITRANSACTIONCOMPLETE_ARGS*>(pvArgs), reinterpret_cast<BA_ONROLLBACKMSITRANSACTIONCOMPLETE_RESULTS*>(pvResults));
1358 break;
1359 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONPAUSEAUTOMATICUPDATESBEGIN:
1360 OnPauseAutomaticUpdatesBeginFallback(reinterpret_cast<BA_ONPAUSEAUTOMATICUPDATESBEGIN_ARGS*>(pvArgs), reinterpret_cast<BA_ONPAUSEAUTOMATICUPDATESBEGIN_RESULTS*>(pvResults));
1361 break;
1362 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONPAUSEAUTOMATICUPDATESCOMPLETE:
1363 OnPauseAutomaticUpdatesCompleteFallback(reinterpret_cast<BA_ONPAUSEAUTOMATICUPDATESCOMPLETE_ARGS*>(pvArgs), reinterpret_cast<BA_ONPAUSEAUTOMATICUPDATESCOMPLETE_RESULTS*>(pvResults));
1364 break;
1365 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONSYSTEMRESTOREPOINTBEGIN:
1366 OnSystemRestorePointBeginFallback(reinterpret_cast<BA_ONSYSTEMRESTOREPOINTBEGIN_ARGS*>(pvArgs), reinterpret_cast<BA_ONSYSTEMRESTOREPOINTBEGIN_RESULTS*>(pvResults));
1367 break;
1368 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONSYSTEMRESTOREPOINTCOMPLETE:
1369 OnSystemRestorePointCompleteFallback(reinterpret_cast<BA_ONSYSTEMRESTOREPOINTCOMPLETE_ARGS*>(pvArgs), reinterpret_cast<BA_ONSYSTEMRESTOREPOINTCOMPLETE_RESULTS*>(pvResults));
1370 break;
1371 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANNEDPACKAGE:
1372 OnPlannedPackageFallback(reinterpret_cast<BA_ONPLANNEDPACKAGE_ARGS*>(pvArgs), reinterpret_cast<BA_ONPLANNEDPACKAGE_RESULTS*>(pvResults));
1373 break;
1374 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEVERIFYPROGRESS:
1375 OnCacheVerifyProgressFallback(reinterpret_cast<BA_ONCACHEVERIFYPROGRESS_ARGS*>(pvArgs), reinterpret_cast<BA_ONCACHEVERIFYPROGRESS_RESULTS*>(pvResults));
1376 break;
1377 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHECONTAINERORPAYLOADVERIFYBEGIN:
1378 OnCacheContainerOrPayloadVerifyBeginFallback(reinterpret_cast<BA_ONCACHECONTAINERORPAYLOADVERIFYBEGIN_ARGS*>(pvArgs), reinterpret_cast<BA_ONCACHECONTAINERORPAYLOADVERIFYBEGIN_RESULTS*>(pvResults));
1379 break;
1380 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHECONTAINERORPAYLOADVERIFYCOMPLETE:
1381 OnCacheContainerOrPayloadVerifyCompleteFallback(reinterpret_cast<BA_ONCACHECONTAINERORPAYLOADVERIFYCOMPLETE_ARGS*>(pvArgs), reinterpret_cast<BA_ONCACHECONTAINERORPAYLOADVERIFYCOMPLETE_RESULTS*>(pvResults));
1382 break;
1383 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHECONTAINERORPAYLOADVERIFYPROGRESS:
1384 OnCacheContainerOrPayloadVerifyProgressFallback(reinterpret_cast<BA_ONCACHECONTAINERORPAYLOADVERIFYPROGRESS_ARGS*>(pvArgs), reinterpret_cast<BA_ONCACHECONTAINERORPAYLOADVERIFYPROGRESS_RESULTS*>(pvResults));
1385 break;
1386 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEPAYLOADEXTRACTBEGIN:
1387 OnCachePayloadExtractBeginFallback(reinterpret_cast<BA_ONCACHEPAYLOADEXTRACTBEGIN_ARGS*>(pvArgs), reinterpret_cast<BA_ONCACHEPAYLOADEXTRACTBEGIN_RESULTS*>(pvResults));
1388 break;
1389 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEPAYLOADEXTRACTCOMPLETE:
1390 OnCachePayloadExtractCompleteFallback(reinterpret_cast<BA_ONCACHEPAYLOADEXTRACTCOMPLETE_ARGS*>(pvArgs), reinterpret_cast<BA_ONCACHEPAYLOADEXTRACTCOMPLETE_RESULTS*>(pvResults));
1391 break;
1392 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEPAYLOADEXTRACTPROGRESS:
1393 OnCachePayloadExtractProgressFallback(reinterpret_cast<BA_ONCACHEPAYLOADEXTRACTPROGRESS_ARGS*>(pvArgs), reinterpret_cast<BA_ONCACHEPAYLOADEXTRACTPROGRESS_RESULTS*>(pvResults));
1394 break;
1395 default:
1396#ifdef DEBUG
1397 BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "WIXSTDBA: Forwarding unknown BA message: %d", message);
1398#endif
1399 m_pfnBAFunctionsProc((BA_FUNCTIONS_MESSAGE)message, pvArgs, pvResults, m_pvBAFunctionsProcContext);
1400 break;
1401 }
1402 }
1403
1404
1405private: // privates
1406 void OnDetectBeginFallback(
1407 __in BA_ONDETECTBEGIN_ARGS* pArgs,
1408 __inout BA_ONDETECTBEGIN_RESULTS* pResults
1409 )
1410 {
1411 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONDETECTBEGIN, pArgs, pResults, m_pvBAFunctionsProcContext);
1412 }
1413
1414 void OnDetectCompleteFallback(
1415 __in BA_ONDETECTCOMPLETE_ARGS* pArgs,
1416 __inout BA_ONDETECTCOMPLETE_RESULTS* pResults
1417 )
1418 {
1419 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONDETECTCOMPLETE, pArgs, pResults, m_pvBAFunctionsProcContext);
1420 }
1421
1422 void OnPlanBeginFallback(
1423 __in BA_ONPLANBEGIN_ARGS* pArgs,
1424 __inout BA_ONPLANBEGIN_RESULTS* pResults
1425 )
1426 {
1427 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONPLANBEGIN, pArgs, pResults, m_pvBAFunctionsProcContext);
1428 }
1429
1430 void OnPlanCompleteFallback(
1431 __in BA_ONPLANCOMPLETE_ARGS* pArgs,
1432 __inout BA_ONPLANCOMPLETE_RESULTS* pResults
1433 )
1434 {
1435 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONPLANCOMPLETE, pArgs, pResults, m_pvBAFunctionsProcContext);
1436 }
1437
1438 void OnShutdownFallback(
1439 __in BA_ONSHUTDOWN_ARGS* pArgs,
1440 __inout BA_ONSHUTDOWN_RESULTS* pResults
1441 )
1442 {
1443 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONSHUTDOWN, pArgs, pResults, m_pvBAFunctionsProcContext);
1444 }
1445
1446 void OnSystemShutdownFallback(
1447 __in BA_ONSYSTEMSHUTDOWN_ARGS* pArgs,
1448 __inout BA_ONSYSTEMSHUTDOWN_RESULTS* pResults
1449 )
1450 {
1451 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONSYSTEMSHUTDOWN, pArgs, pResults, m_pvBAFunctionsProcContext);
1452 }
1453
1454 void OnDetectForwardCompatibleBundleFallback(
1455 __in BA_ONDETECTFORWARDCOMPATIBLEBUNDLE_ARGS* pArgs,
1456 __inout BA_ONDETECTFORWARDCOMPATIBLEBUNDLE_RESULTS* pResults
1457 )
1458 {
1459 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONDETECTFORWARDCOMPATIBLEBUNDLE, pArgs, pResults, m_pvBAFunctionsProcContext);
1460 }
1461
1462 void OnDetectUpdateBeginFallback(
1463 __in BA_ONDETECTUPDATEBEGIN_ARGS* pArgs,
1464 __inout BA_ONDETECTUPDATEBEGIN_RESULTS* pResults
1465 )
1466 {
1467 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONDETECTUPDATEBEGIN, pArgs, pResults, m_pvBAFunctionsProcContext);
1468 }
1469
1470 void OnDetectUpdateFallback(
1471 __in BA_ONDETECTUPDATE_ARGS* pArgs,
1472 __inout BA_ONDETECTUPDATE_RESULTS* pResults
1473 )
1474 {
1475 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONDETECTUPDATE, pArgs, pResults, m_pvBAFunctionsProcContext);
1476 }
1477
1478 void OnDetectUpdateCompleteFallback(
1479 __in BA_ONDETECTUPDATECOMPLETE_ARGS* pArgs,
1480 __inout BA_ONDETECTUPDATECOMPLETE_RESULTS* pResults
1481 )
1482 {
1483 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONDETECTUPDATECOMPLETE, pArgs, pResults, m_pvBAFunctionsProcContext);
1484 }
1485
1486 void OnDetectRelatedBundleFallback(
1487 __in BA_ONDETECTRELATEDBUNDLE_ARGS* pArgs,
1488 __inout BA_ONDETECTRELATEDBUNDLE_RESULTS* pResults
1489 )
1490 {
1491 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONDETECTRELATEDBUNDLE, pArgs, pResults, m_pvBAFunctionsProcContext);
1492 }
1493
1494 void OnDetectPackageBeginFallback(
1495 __in BA_ONDETECTPACKAGEBEGIN_ARGS* pArgs,
1496 __inout BA_ONDETECTPACKAGEBEGIN_RESULTS* pResults
1497 )
1498 {
1499 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONDETECTPACKAGEBEGIN, pArgs, pResults, m_pvBAFunctionsProcContext);
1500 }
1501
1502 void OnDetectRelatedMsiPackageFallback(
1503 __in BA_ONDETECTRELATEDMSIPACKAGE_ARGS* pArgs,
1504 __inout BA_ONDETECTRELATEDMSIPACKAGE_RESULTS* pResults
1505 )
1506 {
1507 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONDETECTRELATEDMSIPACKAGE, pArgs, pResults, m_pvBAFunctionsProcContext);
1508 }
1509
1510 void OnDetectPatchTargetFallback(
1511 __in BA_ONDETECTPATCHTARGET_ARGS* pArgs,
1512 __inout BA_ONDETECTPATCHTARGET_RESULTS* pResults
1513 )
1514 {
1515 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONDETECTPATCHTARGET, pArgs, pResults, m_pvBAFunctionsProcContext);
1516 }
1517
1518 void OnDetectMsiFeatureFallback(
1519 __in BA_ONDETECTMSIFEATURE_ARGS* pArgs,
1520 __inout BA_ONDETECTMSIFEATURE_RESULTS* pResults
1521 )
1522 {
1523 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONDETECTMSIFEATURE, pArgs, pResults, m_pvBAFunctionsProcContext);
1524 }
1525
1526 void OnDetectPackageCompleteFallback(
1527 __in BA_ONDETECTPACKAGECOMPLETE_ARGS* pArgs,
1528 __inout BA_ONDETECTPACKAGECOMPLETE_RESULTS* pResults
1529 )
1530 {
1531 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONDETECTPACKAGECOMPLETE, pArgs, pResults, m_pvBAFunctionsProcContext);
1532 }
1533
1534 void OnPlanRelatedBundleFallback(
1535 __in BA_ONPLANRELATEDBUNDLE_ARGS* pArgs,
1536 __inout BA_ONPLANRELATEDBUNDLE_RESULTS* pResults
1537 )
1538 {
1539 BOOTSTRAPPER_REQUEST_STATE requestedState = pResults->requestedState;
1540 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONPLANRELATEDBUNDLE, pArgs, pResults, m_pvBAFunctionsProcContext);
1541 BalLogId(BOOTSTRAPPER_LOG_LEVEL_STANDARD, MSG_WIXSTDBA_PLANNED_RELATED_BUNDLE, m_hModule, pArgs->wzBundleId, LoggingRequestStateToString(requestedState), LoggingRequestStateToString(pResults->requestedState));
1542 }
1543
1544 void OnPlanPackageBeginFallback(
1545 __in BA_ONPLANPACKAGEBEGIN_ARGS* pArgs,
1546 __inout BA_ONPLANPACKAGEBEGIN_RESULTS* pResults
1547 )
1548 {
1549 BOOTSTRAPPER_REQUEST_STATE requestedState = pResults->requestedState;
1550 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONPLANPACKAGEBEGIN, pArgs, pResults, m_pvBAFunctionsProcContext);
1551 BalLogId(BOOTSTRAPPER_LOG_LEVEL_STANDARD, MSG_WIXSTDBA_PLANNED_PACKAGE, m_hModule, pArgs->wzPackageId, LoggingRequestStateToString(requestedState), LoggingRequestStateToString(pResults->requestedState));
1552 }
1553
1554 void OnPlanPatchTargetFallback(
1555 __in BA_ONPLANPATCHTARGET_ARGS* pArgs,
1556 __inout BA_ONPLANPATCHTARGET_RESULTS* pResults
1557 )
1558 {
1559 BOOTSTRAPPER_REQUEST_STATE requestedState = pResults->requestedState;
1560 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONPLANPATCHTARGET, pArgs, pResults, m_pvBAFunctionsProcContext);
1561 BalLogId(BOOTSTRAPPER_LOG_LEVEL_STANDARD, MSG_WIXSTDBA_PLANNED_TARGET_MSI_PACKAGE, m_hModule, pArgs->wzPackageId, pArgs->wzProductCode, LoggingRequestStateToString(requestedState), LoggingRequestStateToString(pResults->requestedState));
1562 }
1563
1564 void OnPlanMsiFeatureFallback(
1565 __in BA_ONPLANMSIFEATURE_ARGS* pArgs,
1566 __inout BA_ONPLANMSIFEATURE_RESULTS* pResults
1567 )
1568 {
1569 BOOTSTRAPPER_FEATURE_STATE requestedState = pResults->requestedState;
1570 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONPLANMSIFEATURE, pArgs, pResults, m_pvBAFunctionsProcContext);
1571 BalLogId(BOOTSTRAPPER_LOG_LEVEL_STANDARD, MSG_WIXSTDBA_PLANNED_MSI_FEATURE, m_hModule, pArgs->wzPackageId, pArgs->wzFeatureId, LoggingMsiFeatureStateToString(requestedState), LoggingMsiFeatureStateToString(pResults->requestedState));
1572 }
1573
1574 void OnPlanPackageCompleteFallback(
1575 __in BA_ONPLANPACKAGECOMPLETE_ARGS* pArgs,
1576 __inout BA_ONPLANPACKAGECOMPLETE_RESULTS* pResults
1577 )
1578 {
1579 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONPLANPACKAGECOMPLETE, pArgs, pResults, m_pvBAFunctionsProcContext);
1580 }
1581
1582 void OnPlannedPackageFallback(
1583 __in BA_ONPLANNEDPACKAGE_ARGS* pArgs,
1584 __inout BA_ONPLANNEDPACKAGE_RESULTS* pResults
1585 )
1586 {
1587 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONPLANNEDPACKAGE, pArgs, pResults, m_pvBAFunctionsProcContext);
1588 }
1589
1590 void OnApplyBeginFallback(
1591 __in BA_ONAPPLYBEGIN_ARGS* pArgs,
1592 __inout BA_ONAPPLYBEGIN_RESULTS* pResults
1593 )
1594 {
1595 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONAPPLYBEGIN, pArgs, pResults, m_pvBAFunctionsProcContext);
1596 }
1597
1598 void OnElevateBeginFallback(
1599 __in BA_ONELEVATEBEGIN_ARGS* pArgs,
1600 __inout BA_ONELEVATEBEGIN_RESULTS* pResults
1601 )
1602 {
1603 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONELEVATEBEGIN, pArgs, pResults, m_pvBAFunctionsProcContext);
1604 }
1605
1606 void OnElevateCompleteFallback(
1607 __in BA_ONELEVATECOMPLETE_ARGS* pArgs,
1608 __inout BA_ONELEVATECOMPLETE_RESULTS* pResults
1609 )
1610 {
1611 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONELEVATECOMPLETE, pArgs, pResults, m_pvBAFunctionsProcContext);
1612 }
1613
1614 void OnProgressFallback(
1615 __in BA_ONPROGRESS_ARGS* pArgs,
1616 __inout BA_ONPROGRESS_RESULTS* pResults
1617 )
1618 {
1619 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONPROGRESS, pArgs, pResults, m_pvBAFunctionsProcContext);
1620 }
1621
1622 void OnErrorFallback(
1623 __in BA_ONERROR_ARGS* pArgs,
1624 __inout BA_ONERROR_RESULTS* pResults
1625 )
1626 {
1627 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONERROR, pArgs, pResults, m_pvBAFunctionsProcContext);
1628 }
1629
1630 void OnRegisterBeginFallback(
1631 __in BA_ONREGISTERBEGIN_ARGS* pArgs,
1632 __inout BA_ONREGISTERBEGIN_RESULTS* pResults
1633 )
1634 {
1635 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONREGISTERBEGIN, pArgs, pResults, m_pvBAFunctionsProcContext);
1636 }
1637
1638 void OnRegisterCompleteFallback(
1639 __in BA_ONREGISTERCOMPLETE_ARGS* pArgs,
1640 __inout BA_ONREGISTERCOMPLETE_RESULTS* pResults
1641 )
1642 {
1643 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONREGISTERCOMPLETE, pArgs, pResults, m_pvBAFunctionsProcContext);
1644 }
1645
1646 void OnCacheBeginFallback(
1647 __in BA_ONCACHEBEGIN_ARGS* pArgs,
1648 __inout BA_ONCACHEBEGIN_RESULTS* pResults
1649 )
1650 {
1651 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONCACHEBEGIN, pArgs, pResults, m_pvBAFunctionsProcContext);
1652 }
1653
1654 void OnCachePackageBeginFallback(
1655 __in BA_ONCACHEPACKAGEBEGIN_ARGS* pArgs,
1656 __inout BA_ONCACHEPACKAGEBEGIN_RESULTS* pResults
1657 )
1658 {
1659 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONCACHEPACKAGEBEGIN, pArgs, pResults, m_pvBAFunctionsProcContext);
1660 }
1661
1662 void OnCacheAcquireBeginFallback(
1663 __in BA_ONCACHEACQUIREBEGIN_ARGS* pArgs,
1664 __inout BA_ONCACHEACQUIREBEGIN_RESULTS* pResults
1665 )
1666 {
1667 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONCACHEACQUIREBEGIN, pArgs, pResults, m_pvBAFunctionsProcContext);
1668 }
1669
1670 void OnCacheAcquireProgressFallback(
1671 __in BA_ONCACHEACQUIREPROGRESS_ARGS* pArgs,
1672 __inout BA_ONCACHEACQUIREPROGRESS_RESULTS* pResults
1673 )
1674 {
1675 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONCACHEACQUIREPROGRESS, pArgs, pResults, m_pvBAFunctionsProcContext);
1676 }
1677
1678 void OnCacheAcquireResolvingFallback(
1679 __in BA_ONCACHEACQUIRERESOLVING_ARGS* pArgs,
1680 __inout BA_ONCACHEACQUIRERESOLVING_RESULTS* pResults
1681 )
1682 {
1683 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONCACHEACQUIRERESOLVING, pArgs, pResults, m_pvBAFunctionsProcContext);
1684 }
1685
1686 void OnCacheAcquireCompleteFallback(
1687 __in BA_ONCACHEACQUIRECOMPLETE_ARGS* pArgs,
1688 __inout BA_ONCACHEACQUIRECOMPLETE_RESULTS* pResults
1689 )
1690 {
1691 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONCACHEACQUIRECOMPLETE, pArgs, pResults, m_pvBAFunctionsProcContext);
1692 }
1693
1694 void OnCacheVerifyBeginFallback(
1695 __in BA_ONCACHEVERIFYBEGIN_ARGS* pArgs,
1696 __inout BA_ONCACHEVERIFYBEGIN_RESULTS* pResults
1697 )
1698 {
1699 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONCACHEVERIFYBEGIN, pArgs, pResults, m_pvBAFunctionsProcContext);
1700 }
1701
1702 void OnCacheVerifyCompleteFallback(
1703 __in BA_ONCACHEVERIFYCOMPLETE_ARGS* pArgs,
1704 __inout BA_ONCACHEVERIFYCOMPLETE_RESULTS* pResults
1705 )
1706 {
1707 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONCACHEVERIFYCOMPLETE, pArgs, pResults, m_pvBAFunctionsProcContext);
1708 }
1709
1710 void OnCachePackageCompleteFallback(
1711 __in BA_ONCACHEPACKAGECOMPLETE_ARGS* pArgs,
1712 __inout BA_ONCACHEPACKAGECOMPLETE_RESULTS* pResults
1713 )
1714 {
1715 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONCACHEPACKAGECOMPLETE, pArgs, pResults, m_pvBAFunctionsProcContext);
1716 }
1717
1718 void OnCacheCompleteFallback(
1719 __in BA_ONCACHECOMPLETE_ARGS* pArgs,
1720 __inout BA_ONCACHECOMPLETE_RESULTS* pResults
1721 )
1722 {
1723 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONCACHECOMPLETE, pArgs, pResults, m_pvBAFunctionsProcContext);
1724 }
1725
1726 void OnExecuteBeginFallback(
1727 __in BA_ONEXECUTEBEGIN_ARGS* pArgs,
1728 __inout BA_ONEXECUTEBEGIN_RESULTS* pResults
1729 )
1730 {
1731 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONEXECUTEBEGIN, pArgs, pResults, m_pvBAFunctionsProcContext);
1732 }
1733
1734 void OnExecutePackageBeginFallback(
1735 __in BA_ONEXECUTEPACKAGEBEGIN_ARGS* pArgs,
1736 __inout BA_ONEXECUTEPACKAGEBEGIN_RESULTS* pResults
1737 )
1738 {
1739 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONEXECUTEPACKAGEBEGIN, pArgs, pResults, m_pvBAFunctionsProcContext);
1740 }
1741
1742 void OnExecutePatchTargetFallback(
1743 __in BA_ONEXECUTEPATCHTARGET_ARGS* pArgs,
1744 __inout BA_ONEXECUTEPATCHTARGET_RESULTS* pResults
1745 )
1746 {
1747 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONEXECUTEPATCHTARGET, pArgs, pResults, m_pvBAFunctionsProcContext);
1748 }
1749
1750 void OnExecuteProgressFallback(
1751 __in BA_ONEXECUTEPROGRESS_ARGS* pArgs,
1752 __inout BA_ONEXECUTEPROGRESS_RESULTS* pResults
1753 )
1754 {
1755 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONEXECUTEPROGRESS, pArgs, pResults, m_pvBAFunctionsProcContext);
1756 }
1757
1758 void OnExecuteMsiMessageFallback(
1759 __in BA_ONEXECUTEMSIMESSAGE_ARGS* pArgs,
1760 __inout BA_ONEXECUTEMSIMESSAGE_RESULTS* pResults
1761 )
1762 {
1763 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONEXECUTEMSIMESSAGE, pArgs, pResults, m_pvBAFunctionsProcContext);
1764 }
1765
1766 void OnExecuteFilesInUseFallback(
1767 __in BA_ONEXECUTEFILESINUSE_ARGS* pArgs,
1768 __inout BA_ONEXECUTEFILESINUSE_RESULTS* pResults
1769 )
1770 {
1771 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONEXECUTEFILESINUSE, pArgs, pResults, m_pvBAFunctionsProcContext);
1772 }
1773
1774 void OnExecutePackageCompleteFallback(
1775 __in BA_ONEXECUTEPACKAGECOMPLETE_ARGS* pArgs,
1776 __inout BA_ONEXECUTEPACKAGECOMPLETE_RESULTS* pResults
1777 )
1778 {
1779 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONEXECUTEPACKAGECOMPLETE, pArgs, pResults, m_pvBAFunctionsProcContext);
1780 }
1781
1782 void OnExecuteCompleteFallback(
1783 __in BA_ONEXECUTECOMPLETE_ARGS* pArgs,
1784 __inout BA_ONEXECUTECOMPLETE_RESULTS* pResults
1785 )
1786 {
1787 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONEXECUTECOMPLETE, pArgs, pResults, m_pvBAFunctionsProcContext);
1788 }
1789
1790 void OnUnregisterBeginFallback(
1791 __in BA_ONUNREGISTERBEGIN_ARGS* pArgs,
1792 __inout BA_ONUNREGISTERBEGIN_RESULTS* pResults
1793 )
1794 {
1795 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONUNREGISTERBEGIN, pArgs, pResults, m_pvBAFunctionsProcContext);
1796 }
1797
1798 void OnUnregisterCompleteFallback(
1799 __in BA_ONUNREGISTERCOMPLETE_ARGS* pArgs,
1800 __inout BA_ONUNREGISTERCOMPLETE_RESULTS* pResults
1801 )
1802 {
1803 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONUNREGISTERCOMPLETE, pArgs, pResults, m_pvBAFunctionsProcContext);
1804 }
1805
1806 void OnApplyCompleteFallback(
1807 __in BA_ONAPPLYCOMPLETE_ARGS* pArgs,
1808 __inout BA_ONAPPLYCOMPLETE_RESULTS* pResults
1809 )
1810 {
1811 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONAPPLYCOMPLETE, pArgs, pResults, m_pvBAFunctionsProcContext);
1812 }
1813
1814 void OnLaunchApprovedExeBeginFallback(
1815 __in BA_ONLAUNCHAPPROVEDEXEBEGIN_ARGS* pArgs,
1816 __inout BA_ONLAUNCHAPPROVEDEXEBEGIN_RESULTS* pResults
1817 )
1818 {
1819 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONLAUNCHAPPROVEDEXEBEGIN, pArgs, pResults, m_pvBAFunctionsProcContext);
1820 }
1821
1822 void OnLaunchApprovedExeCompleteFallback(
1823 __in BA_ONLAUNCHAPPROVEDEXECOMPLETE_ARGS* pArgs,
1824 __inout BA_ONLAUNCHAPPROVEDEXECOMPLETE_RESULTS* pResults
1825 )
1826 {
1827 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONLAUNCHAPPROVEDEXECOMPLETE, pArgs, pResults, m_pvBAFunctionsProcContext);
1828 }
1829
1830 void OnPlanMsiPackageFallback(
1831 __in BA_ONPLANMSIPACKAGE_ARGS* pArgs,
1832 __inout BA_ONPLANMSIPACKAGE_RESULTS* pResults
1833 )
1834 {
1835 BURN_MSI_PROPERTY actionMsiProperty = pResults->actionMsiProperty;
1836 INSTALLUILEVEL uiLevel = pResults->uiLevel;
1837 BOOL fDisableExternalUiHandler = pResults->fDisableExternalUiHandler;
1838 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONPLANMSIPACKAGE, pArgs, pResults, m_pvBAFunctionsProcContext);
1839 BalLogId(BOOTSTRAPPER_LOG_LEVEL_STANDARD, MSG_WIXSTDBA_PLANNED_MSI_PACKAGE, m_hModule, pArgs->wzPackageId, actionMsiProperty, uiLevel, fDisableExternalUiHandler ? "yes" : "no", pResults->actionMsiProperty, pResults->uiLevel, pResults->fDisableExternalUiHandler ? "yes" : "no");
1840 }
1841
1842 void OnBeginMsiTransactionBeginFallback(
1843 __in BA_ONBEGINMSITRANSACTIONBEGIN_ARGS* pArgs,
1844 __inout BA_ONBEGINMSITRANSACTIONBEGIN_RESULTS* pResults
1845 )
1846 {
1847 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONBEGINMSITRANSACTIONBEGIN, pArgs, pResults, m_pvBAFunctionsProcContext);
1848 }
1849
1850 void OnBeginMsiTransactionCompleteFallback(
1851 __in BA_ONBEGINMSITRANSACTIONCOMPLETE_ARGS* pArgs,
1852 __inout BA_ONBEGINMSITRANSACTIONCOMPLETE_RESULTS* pResults
1853 )
1854 {
1855 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONBEGINMSITRANSACTIONCOMPLETE, pArgs, pResults, m_pvBAFunctionsProcContext);
1856 }
1857
1858 void OnCommitMsiTransactionBeginFallback(
1859 __in BA_ONCOMMITMSITRANSACTIONBEGIN_ARGS* pArgs,
1860 __inout BA_ONCOMMITMSITRANSACTIONBEGIN_RESULTS* pResults
1861 )
1862 {
1863 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONCOMMITMSITRANSACTIONBEGIN, pArgs, pResults, m_pvBAFunctionsProcContext);
1864 }
1865
1866 void OnCommitMsiTransactionCompleteFallback(
1867 __in BA_ONCOMMITMSITRANSACTIONCOMPLETE_ARGS* pArgs,
1868 __inout BA_ONCOMMITMSITRANSACTIONCOMPLETE_RESULTS* pResults
1869 )
1870 {
1871 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONCOMMITMSITRANSACTIONCOMPLETE, pArgs, pResults, m_pvBAFunctionsProcContext);
1872 }
1873
1874 void OnRollbackMsiTransactionBeginFallback(
1875 __in BA_ONROLLBACKMSITRANSACTIONBEGIN_ARGS* pArgs,
1876 __inout BA_ONROLLBACKMSITRANSACTIONBEGIN_RESULTS* pResults
1877 )
1878 {
1879 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONROLLBACKMSITRANSACTIONBEGIN, pArgs, pResults, m_pvBAFunctionsProcContext);
1880 }
1881
1882 void OnRollbackMsiTransactionCompleteFallback(
1883 __in BA_ONROLLBACKMSITRANSACTIONCOMPLETE_ARGS* pArgs,
1884 __inout BA_ONROLLBACKMSITRANSACTIONCOMPLETE_RESULTS* pResults
1885 )
1886 {
1887 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONROLLBACKMSITRANSACTIONCOMPLETE, pArgs, pResults, m_pvBAFunctionsProcContext);
1888 }
1889
1890 void OnPauseAutomaticUpdatesBeginFallback(
1891 __in BA_ONPAUSEAUTOMATICUPDATESBEGIN_ARGS* pArgs,
1892 __inout BA_ONPAUSEAUTOMATICUPDATESBEGIN_RESULTS* pResults
1893 )
1894 {
1895 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONPAUSEAUTOMATICUPDATESBEGIN, pArgs, pResults, m_pvBAFunctionsProcContext);
1896 }
1897
1898 void OnPauseAutomaticUpdatesCompleteFallback(
1899 __in BA_ONPAUSEAUTOMATICUPDATESCOMPLETE_ARGS* pArgs,
1900 __inout BA_ONPAUSEAUTOMATICUPDATESCOMPLETE_RESULTS* pResults
1901 )
1902 {
1903 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONPAUSEAUTOMATICUPDATESCOMPLETE, pArgs, pResults, m_pvBAFunctionsProcContext);
1904 }
1905
1906 void OnSystemRestorePointBeginFallback(
1907 __in BA_ONSYSTEMRESTOREPOINTBEGIN_ARGS* pArgs,
1908 __inout BA_ONSYSTEMRESTOREPOINTBEGIN_RESULTS* pResults
1909 )
1910 {
1911 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONSYSTEMRESTOREPOINTBEGIN, pArgs, pResults, m_pvBAFunctionsProcContext);
1912 }
1913
1914 void OnSystemRestorePointCompleteFallback(
1915 __in BA_ONSYSTEMRESTOREPOINTCOMPLETE_ARGS* pArgs,
1916 __inout BA_ONSYSTEMRESTOREPOINTCOMPLETE_RESULTS* pResults
1917 )
1918 {
1919 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONSYSTEMRESTOREPOINTCOMPLETE, pArgs, pResults, m_pvBAFunctionsProcContext);
1920 }
1921
1922 void OnPlanForwardCompatibleBundleFallback(
1923 __in BA_ONPLANFORWARDCOMPATIBLEBUNDLE_ARGS* pArgs,
1924 __inout BA_ONPLANFORWARDCOMPATIBLEBUNDLE_RESULTS* pResults
1925 )
1926 {
1927 BOOL fIgnoreBundle = pResults->fIgnoreBundle;
1928 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONPLANFORWARDCOMPATIBLEBUNDLE, pArgs, pResults, m_pvBAFunctionsProcContext);
1929 BalLogId(BOOTSTRAPPER_LOG_LEVEL_STANDARD, MSG_WIXSTDBA_PLANNED_FORWARD_COMPATIBLE_BUNDLE, m_hModule, pArgs->wzBundleId, fIgnoreBundle ? "ignore" : "enable", pResults->fIgnoreBundle ? "ignore" : "enable");
1930 }
1931
1932 void OnCacheVerifyProgressFallback(
1933 __in BA_ONCACHEVERIFYPROGRESS_ARGS* pArgs,
1934 __inout BA_ONCACHEVERIFYPROGRESS_RESULTS* pResults
1935 )
1936 {
1937 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONCACHEVERIFYPROGRESS, pArgs, pResults, m_pvBAFunctionsProcContext);
1938 }
1939
1940 void OnCacheContainerOrPayloadVerifyBeginFallback(
1941 __in BA_ONCACHECONTAINERORPAYLOADVERIFYBEGIN_ARGS* pArgs,
1942 __inout BA_ONCACHECONTAINERORPAYLOADVERIFYBEGIN_RESULTS* pResults
1943 )
1944 {
1945 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONCACHECONTAINERORPAYLOADVERIFYBEGIN, pArgs, pResults, m_pvBAFunctionsProcContext);
1946 }
1947
1948 void OnCacheContainerOrPayloadVerifyCompleteFallback(
1949 __in BA_ONCACHECONTAINERORPAYLOADVERIFYCOMPLETE_ARGS* pArgs,
1950 __inout BA_ONCACHECONTAINERORPAYLOADVERIFYCOMPLETE_RESULTS* pResults
1951 )
1952 {
1953 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONCACHECONTAINERORPAYLOADVERIFYCOMPLETE, pArgs, pResults, m_pvBAFunctionsProcContext);
1954 }
1955
1956 void OnCacheContainerOrPayloadVerifyProgressFallback(
1957 __in BA_ONCACHECONTAINERORPAYLOADVERIFYPROGRESS_ARGS* pArgs,
1958 __inout BA_ONCACHECONTAINERORPAYLOADVERIFYPROGRESS_RESULTS* pResults
1959 )
1960 {
1961 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONCACHECONTAINERORPAYLOADVERIFYPROGRESS, pArgs, pResults, m_pvBAFunctionsProcContext);
1962 }
1963
1964 void OnCachePayloadExtractBeginFallback(
1965 __in BA_ONCACHEPAYLOADEXTRACTBEGIN_ARGS* pArgs,
1966 __inout BA_ONCACHEPAYLOADEXTRACTBEGIN_RESULTS* pResults
1967 )
1968 {
1969 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONCACHEPAYLOADEXTRACTBEGIN, pArgs, pResults, m_pvBAFunctionsProcContext);
1970 }
1971
1972 void OnCachePayloadExtractCompleteFallback(
1973 __in BA_ONCACHEPAYLOADEXTRACTCOMPLETE_ARGS* pArgs,
1974 __inout BA_ONCACHEPAYLOADEXTRACTCOMPLETE_RESULTS* pResults
1975 )
1976 {
1977 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONCACHEPAYLOADEXTRACTCOMPLETE, pArgs, pResults, m_pvBAFunctionsProcContext);
1978 }
1979
1980 void OnCachePayloadExtractProgressFallback(
1981 __in BA_ONCACHEPAYLOADEXTRACTPROGRESS_ARGS* pArgs,
1982 __inout BA_ONCACHEPAYLOADEXTRACTPROGRESS_RESULTS* pResults
1983 )
1984 {
1985 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONCACHEPAYLOADEXTRACTPROGRESS, pArgs, pResults, m_pvBAFunctionsProcContext);
1986 }
1987
1988 //
1989 // UiThreadProc - entrypoint for UI thread.
1990 //
1991 static DWORD WINAPI UiThreadProc(
1992 __in LPVOID pvContext
1993 )
1994 {
1995 HRESULT hr = S_OK;
1996 CWixStandardBootstrapperApplication* pThis = (CWixStandardBootstrapperApplication*)pvContext;
1997 BOOL fComInitialized = FALSE;
1998 BOOL fRet = FALSE;
1999 MSG msg = { };
2000
2001 // Initialize COM and theme.
2002 hr = ::CoInitialize(NULL);
2003 BalExitOnFailure(hr, "Failed to initialize COM.");
2004 fComInitialized = TRUE;
2005
2006 hr = ThemeInitialize(pThis->m_hModule);
2007 BalExitOnFailure(hr, "Failed to initialize theme manager.");
2008
2009 hr = pThis->InitializeData();
2010 BalExitOnFailure(hr, "Failed to initialize data in bootstrapper application.");
2011
2012 // Create main window.
2013 pThis->InitializeTaskbarButton();
2014 hr = pThis->CreateMainWindow();
2015 BalExitOnFailure(hr, "Failed to create main window.");
2016
2017 if (FAILED(pThis->m_hrFinal))
2018 {
2019 pThis->SetState(WIXSTDBA_STATE_FAILED, hr);
2020 ::PostMessageW(pThis->m_hWnd, WM_WIXSTDBA_SHOW_FAILURE, 0, 0);
2021 }
2022 else
2023 {
2024 // Okay, we're ready for packages now.
2025 pThis->SetState(WIXSTDBA_STATE_INITIALIZED, hr);
2026 ::PostMessageW(pThis->m_hWnd, BOOTSTRAPPER_ACTION_HELP == pThis->m_command.action ? WM_WIXSTDBA_SHOW_HELP : WM_WIXSTDBA_DETECT_PACKAGES, 0, 0);
2027 }
2028
2029 // message pump
2030 while (0 != (fRet = ::GetMessageW(&msg, NULL, 0, 0)))
2031 {
2032 if (-1 == fRet)
2033 {
2034 hr = E_UNEXPECTED;
2035 BalExitOnFailure(hr, "Unexpected return value from message pump.");
2036 }
2037 else if (!ThemeHandleKeyboardMessage(pThis->m_pTheme, msg.hwnd, &msg))
2038 {
2039 ::TranslateMessage(&msg);
2040 ::DispatchMessageW(&msg);
2041 }
2042 }
2043
2044 // Succeeded thus far, check to see if anything went wrong while actually
2045 // executing changes.
2046 if (FAILED(pThis->m_hrFinal))
2047 {
2048 hr = pThis->m_hrFinal;
2049 }
2050 else if (pThis->CheckCanceled())
2051 {
2052 hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT);
2053 }
2054
2055 LExit:
2056 // destroy main window
2057 pThis->DestroyMainWindow();
2058 pThis->UninitializeTaskbarButton();
2059
2060 // initiate engine shutdown
2061 DWORD dwQuit = HRESULT_CODE(hr);
2062 if (BOOTSTRAPPER_APPLY_RESTART_INITIATED == pThis->m_restartResult)
2063 {
2064 dwQuit = ERROR_SUCCESS_REBOOT_INITIATED;
2065 }
2066 else if (BOOTSTRAPPER_APPLY_RESTART_REQUIRED == pThis->m_restartResult)
2067 {
2068 dwQuit = ERROR_SUCCESS_REBOOT_REQUIRED;
2069 }
2070 pThis->m_pEngine->Quit(dwQuit);
2071
2072 ReleaseTheme(pThis->m_pTheme);
2073 ThemeUninitialize();
2074
2075 // uninitialize COM
2076 if (fComInitialized)
2077 {
2078 ::CoUninitialize();
2079 }
2080
2081 return hr;
2082 }
2083
2084
2085 //
2086 // InitializeData - initializes all the package and prerequisite information.
2087 //
2088 HRESULT InitializeData()
2089 {
2090 HRESULT hr = S_OK;
2091 LPWSTR sczModulePath = NULL;
2092 IXMLDOMDocument *pixdManifest = NULL;
2093
2094 hr = BalManifestLoad(m_hModule, &pixdManifest);
2095 BalExitOnFailure(hr, "Failed to load bootstrapper application manifest.");
2096
2097 hr = ParseOverridableVariablesFromXml(pixdManifest);
2098 BalExitOnFailure(hr, "Failed to read overridable variables.");
2099
2100 hr = ProcessCommandLine(&m_sczLanguage);
2101 ExitOnFailure(hr, "Unknown commandline parameters.");
2102
2103 hr = PathRelativeToModule(&sczModulePath, NULL, m_hModule);
2104 BalExitOnFailure(hr, "Failed to get module path.");
2105
2106 hr = LoadLocalization(sczModulePath, m_sczLanguage);
2107 ExitOnFailure(hr, "Failed to load localization.");
2108
2109 hr = LoadTheme(sczModulePath, m_sczLanguage);
2110 ExitOnFailure(hr, "Failed to load theme.");
2111
2112 hr = BalInfoParseFromXml(&m_Bundle, pixdManifest);
2113 BalExitOnFailure(hr, "Failed to load bundle information.");
2114
2115 hr = BalConditionsParseFromXml(&m_Conditions, pixdManifest, m_pWixLoc);
2116 BalExitOnFailure(hr, "Failed to load conditions from XML.");
2117
2118 hr = LoadBAFunctions(pixdManifest);
2119 BalExitOnFailure(hr, "Failed to load bootstrapper functions.");
2120
2121 GetBundleFileVersion();
2122 // don't fail if we couldn't get the version info; best-effort only
2123
2124 hr = InitializePackageInfo();
2125 BalExitOnFailure(hr, "Failed to initialize wixstdba package information.");
2126
2127 if (m_fPrereq)
2128 {
2129 hr = InitializePrerequisiteInformation();
2130 BalExitOnFailure(hr, "Failed to initialize prerequisite information.");
2131 }
2132 else
2133 {
2134 hr = ParseBootstrapperApplicationDataFromXml(pixdManifest);
2135 BalExitOnFailure(hr, "Failed to read bootstrapper application data.");
2136 }
2137
2138 if (BOOTSTRAPPER_ACTION_CACHE == m_plannedAction)
2139 {
2140 if (m_fSupportCacheOnly)
2141 {
2142 // Doesn't make sense to prompt the user if cache only is requested.
2143 if (BOOTSTRAPPER_DISPLAY_PASSIVE < m_command.display)
2144 {
2145 m_command.display = BOOTSTRAPPER_DISPLAY_PASSIVE;
2146 }
2147
2148 m_command.action = BOOTSTRAPPER_ACTION_CACHE;
2149 }
2150 else
2151 {
2152 BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Ignoring attempt to only cache a bundle that does not explicitly support it.");
2153 m_plannedAction = BOOTSTRAPPER_ACTION_UNKNOWN;
2154 }
2155 }
2156
2157 LExit:
2158 ReleaseObject(pixdManifest);
2159 ReleaseStr(sczModulePath);
2160
2161 return hr;
2162 }
2163
2164
2165 //
2166 // ProcessCommandLine - process the provided command line arguments.
2167 //
2168 HRESULT ProcessCommandLine(
2169 __inout LPWSTR* psczLanguage
2170 )
2171 {
2172 HRESULT hr = S_OK;
2173 int argc = 0;
2174 LPWSTR* argv = NULL;
2175 LPWSTR sczVariableName = NULL;
2176 LPWSTR sczVariableValue = NULL;
2177
2178 if (m_command.wzCommandLine && *m_command.wzCommandLine)
2179 {
2180 hr = AppParseCommandLine(m_command.wzCommandLine, &argc, &argv);
2181 ExitOnFailure(hr, "Failed to parse command line.");
2182
2183 for (int i = 0; i < argc; ++i)
2184 {
2185 if (argv[i][0] == L'-' || argv[i][0] == L'/')
2186 {
2187 if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, L"lang", -1))
2188 {
2189 if (i + 1 >= argc)
2190 {
2191 hr = E_INVALIDARG;
2192 BalExitOnFailure(hr, "Must specify a language.");
2193 }
2194
2195 ++i;
2196
2197 hr = StrAllocString(psczLanguage, &argv[i][0], 0);
2198 BalExitOnFailure(hr, "Failed to copy language.");
2199 }
2200 }
2201 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, L"cache", -1))
2202 {
2203 m_plannedAction = BOOTSTRAPPER_ACTION_CACHE;
2204 }
2205 else if (m_sdOverridableVariables)
2206 {
2207 const wchar_t* pwc = wcschr(argv[i], L'=');
2208 if (pwc)
2209 {
2210 hr = StrAllocString(&sczVariableName, argv[i], pwc - argv[i]);
2211 BalExitOnFailure(hr, "Failed to copy variable name.");
2212
2213 hr = DictKeyExists(m_sdOverridableVariables, sczVariableName);
2214 if (E_NOTFOUND == hr)
2215 {
2216 BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Ignoring attempt to set non-overridable variable: '%ls'.", sczVariableName);
2217 hr = S_OK;
2218 continue;
2219 }
2220 ExitOnFailure(hr, "Failed to check the dictionary of overridable variables.");
2221
2222 hr = StrAllocString(&sczVariableValue, ++pwc, 0);
2223 BalExitOnFailure(hr, "Failed to copy variable value.");
2224
2225 hr = m_pEngine->SetVariableString(sczVariableName, sczVariableValue, FALSE);
2226 BalExitOnFailure(hr, "Failed to set variable.");
2227 }
2228 else
2229 {
2230 BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Ignoring unknown argument: %ls", argv[i]);
2231 }
2232 }
2233 }
2234 }
2235
2236 LExit:
2237 if (argv)
2238 {
2239 AppFreeCommandLineArgs(argv);
2240 }
2241
2242 ReleaseStr(sczVariableName);
2243 ReleaseStr(sczVariableValue);
2244
2245 return hr;
2246 }
2247
2248 HRESULT LoadLocalization(
2249 __in_z LPCWSTR wzModulePath,
2250 __in_z_opt LPCWSTR wzLanguage
2251 )
2252 {
2253 HRESULT hr = S_OK;
2254 LPWSTR sczLocPath = NULL;
2255 LPWSTR sczFormatted = NULL;
2256 LPCWSTR wzLocFileName = m_fPrereq ? L"mbapreq.wxl" : L"thm.wxl";
2257
2258 // Find and load .wxl file.
2259 hr = LocProbeForFile(wzModulePath, wzLocFileName, wzLanguage, &sczLocPath);
2260 BalExitOnFailure(hr, "Failed to probe for loc file: %ls in path: %ls", wzLocFileName, wzModulePath);
2261
2262 hr = LocLoadFromFile(sczLocPath, &m_pWixLoc);
2263 BalExitOnFailure(hr, "Failed to load loc file from path: %ls", sczLocPath);
2264
2265 // Set WixStdBALanguageId to .wxl language id.
2266 if (WIX_LOCALIZATION_LANGUAGE_NOT_SET != m_pWixLoc->dwLangId)
2267 {
2268 ::SetThreadLocale(m_pWixLoc->dwLangId);
2269
2270 hr = m_pEngine->SetVariableNumeric(WIXSTDBA_VARIABLE_LANGUAGE_ID, m_pWixLoc->dwLangId);
2271 BalExitOnFailure(hr, "Failed to set WixStdBALanguageId variable.");
2272 }
2273
2274 // Load ConfirmCancelMessage.
2275 hr = StrAllocString(&m_sczConfirmCloseMessage, L"#(loc.ConfirmCancelMessage)", 0);
2276 ExitOnFailure(hr, "Failed to initialize confirm message loc identifier.");
2277
2278 hr = LocLocalizeString(m_pWixLoc, &m_sczConfirmCloseMessage);
2279 BalExitOnFailure(hr, "Failed to localize confirm close message: %ls", m_sczConfirmCloseMessage);
2280
2281 hr = BalFormatString(m_sczConfirmCloseMessage, &sczFormatted);
2282 if (SUCCEEDED(hr))
2283 {
2284 ReleaseStr(m_sczConfirmCloseMessage);
2285 m_sczConfirmCloseMessage = sczFormatted;
2286 sczFormatted = NULL;
2287 }
2288
2289 LExit:
2290 ReleaseStr(sczFormatted);
2291 ReleaseStr(sczLocPath);
2292
2293 return hr;
2294 }
2295
2296
2297 HRESULT LoadTheme(
2298 __in_z LPCWSTR wzModulePath,
2299 __in_z_opt LPCWSTR wzLanguage
2300 )
2301 {
2302 HRESULT hr = S_OK;
2303 LPWSTR sczThemePath = NULL;
2304 LPCWSTR wzThemeFileName = m_fPrereq ? L"mbapreq.thm" : L"thm.xml";
2305
2306 hr = LocProbeForFile(wzModulePath, wzThemeFileName, wzLanguage, &sczThemePath);
2307 BalExitOnFailure(hr, "Failed to probe for theme file: %ls in path: %ls", wzThemeFileName, wzModulePath);
2308
2309 hr = ThemeLoadFromFile(sczThemePath, &m_pTheme);
2310 BalExitOnFailure(hr, "Failed to load theme from path: %ls", sczThemePath);
2311
2312 hr = ThemeRegisterVariableCallbacks(m_pTheme, EvaluateVariableConditionCallback, FormatVariableStringCallback, GetVariableNumericCallback, SetVariableNumericCallback, GetVariableStringCallback, SetVariableStringCallback, NULL);
2313 BalExitOnFailure(hr, "Failed to register variable theme callbacks.");
2314
2315 hr = ThemeLocalize(m_pTheme, m_pWixLoc);
2316 BalExitOnFailure(hr, "Failed to localize theme: %ls", sczThemePath);
2317
2318 LExit:
2319 ReleaseStr(sczThemePath);
2320
2321 return hr;
2322 }
2323
2324
2325 HRESULT ParseOverridableVariablesFromXml(
2326 __in IXMLDOMDocument* pixdManifest
2327 )
2328 {
2329 HRESULT hr = S_OK;
2330 IXMLDOMNode* pNode = NULL;
2331 IXMLDOMNodeList* pNodes = NULL;
2332 DWORD cNodes = 0;
2333 LPWSTR scz = NULL;
2334
2335 // Get the list of variables users can override on the command line.
2336 hr = XmlSelectNodes(pixdManifest, L"/BootstrapperApplicationData/WixStdbaOverridableVariable", &pNodes);
2337 if (S_FALSE == hr)
2338 {
2339 ExitFunction1(hr = S_OK);
2340 }
2341 ExitOnFailure(hr, "Failed to select overridable variable nodes.");
2342
2343 hr = pNodes->get_length((long*)&cNodes);
2344 ExitOnFailure(hr, "Failed to get overridable variable node count.");
2345
2346 if (cNodes)
2347 {
2348 hr = DictCreateStringList(&m_sdOverridableVariables, 32, DICT_FLAG_NONE);
2349 ExitOnFailure(hr, "Failed to create the string dictionary.");
2350
2351 for (DWORD i = 0; i < cNodes; ++i)
2352 {
2353 hr = XmlNextElement(pNodes, &pNode, NULL);
2354 ExitOnFailure(hr, "Failed to get next node.");
2355
2356 // @Name
2357 hr = XmlGetAttributeEx(pNode, L"Name", &scz);
2358 ExitOnFailure(hr, "Failed to get @Name.");
2359
2360 hr = DictAddKey(m_sdOverridableVariables, scz);
2361 ExitOnFailure(hr, "Failed to add \"%ls\" to the string dictionary.", scz);
2362
2363 // prepare next iteration
2364 ReleaseNullObject(pNode);
2365 }
2366 }
2367
2368 LExit:
2369 ReleaseObject(pNode);
2370 ReleaseObject(pNodes);
2371 ReleaseStr(scz);
2372 return hr;
2373 }
2374
2375
2376 HRESULT InitializePackageInfo()
2377 {
2378 HRESULT hr = S_OK;
2379 BAL_INFO_PACKAGE* pPackage = NULL;
2380
2381 for (DWORD i = 0; i < m_Bundle.packages.cPackages; ++i)
2382 {
2383 pPackage = &m_Bundle.packages.rgPackages[i];
2384
2385 hr = InitializePackageInfoForPackage(pPackage);
2386 BalExitOnFailure(hr, "Failed to initialize wixstdba package info for package: %ls.", pPackage->sczId);
2387 }
2388
2389 LExit:
2390 return hr;
2391 }
2392
2393
2394 HRESULT InitializePackageInfoForPackage(
2395 __in BAL_INFO_PACKAGE* pPackage
2396 )
2397 {
2398 HRESULT hr = S_OK;
2399
2400 pPackage->pvCustomData = MemAlloc(sizeof(WIXSTDBA_PACKAGE_INFO), TRUE);
2401 BalExitOnNull(pPackage->pvCustomData, hr, E_OUTOFMEMORY, "Failed to allocate memory for wixstdba package info.");
2402
2403 LExit:
2404 return hr;
2405 }
2406
2407
2408 HRESULT InitializePrerequisiteInformation()
2409 {
2410 HRESULT hr = S_OK;
2411 BAL_INFO_PACKAGE* pPackage = NULL;
2412
2413 for (DWORD i = 0; i < m_Bundle.packages.cPackages; ++i)
2414 {
2415 pPackage = &m_Bundle.packages.rgPackages[i];
2416 if (!pPackage->fPrereqPackage)
2417 {
2418 continue;
2419 }
2420
2421 if (pPackage->sczPrereqLicenseFile)
2422 {
2423 if (m_sczLicenseFile)
2424 {
2425 hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
2426 BalExitOnFailure(hr, "More than one license file specified in prerequisite info.");
2427 }
2428
2429 hr = StrAllocString(&m_sczLicenseFile, pPackage->sczPrereqLicenseFile, 0);
2430 BalExitOnFailure(hr, "Failed to copy license file location from prereq package.");
2431 }
2432
2433 if (pPackage->sczPrereqLicenseUrl)
2434 {
2435 if (m_sczLicenseUrl)
2436 {
2437 hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
2438 BalExitOnFailure(hr, "More than one license URL specified in prerequisite info.");
2439 }
2440
2441 hr = StrAllocString(&m_sczLicenseUrl, pPackage->sczPrereqLicenseUrl, 0);
2442 BalExitOnFailure(hr, "Failed to copy license URL from prereq package.");
2443 }
2444 }
2445
2446 LExit:
2447 return hr;
2448 }
2449
2450
2451 HRESULT ParseBootstrapperApplicationDataFromXml(
2452 __in IXMLDOMDocument* pixdManifest
2453 )
2454 {
2455 HRESULT hr = S_OK;
2456 IXMLDOMNode* pNode = NULL;
2457 DWORD dwBool = 0;
2458
2459 hr = XmlSelectSingleNode(pixdManifest, L"/BootstrapperApplicationData/WixStdbaInformation", &pNode);
2460 if (S_FALSE == hr)
2461 {
2462 hr = E_INVALIDARG;
2463 }
2464 BalExitOnFailure(hr, "BootstrapperApplication.xml manifest is missing wixstdba information.");
2465
2466 hr = XmlGetAttributeEx(pNode, L"LicenseFile", &m_sczLicenseFile);
2467 if (E_NOTFOUND == hr)
2468 {
2469 hr = S_OK;
2470 }
2471 BalExitOnFailure(hr, "Failed to get license file.");
2472
2473 hr = XmlGetAttributeEx(pNode, L"LicenseUrl", &m_sczLicenseUrl);
2474 if (E_NOTFOUND == hr)
2475 {
2476 hr = S_OK;
2477 }
2478 BalExitOnFailure(hr, "Failed to get license URL.");
2479
2480 ReleaseObject(pNode);
2481
2482 hr = XmlSelectSingleNode(pixdManifest, L"/BootstrapperApplicationData/WixStdbaOptions", &pNode);
2483 if (S_FALSE == hr)
2484 {
2485 ExitFunction1(hr = S_OK);
2486 }
2487 BalExitOnFailure(hr, "Failed to read wixstdba options from BootstrapperApplication.xml manifest.");
2488
2489 hr = XmlGetAttributeNumber(pNode, L"SuppressOptionsUI", &dwBool);
2490 if (S_FALSE == hr)
2491 {
2492 hr = S_OK;
2493 }
2494 else if (SUCCEEDED(hr) && dwBool)
2495 {
2496 hr = BalSetNumericVariable(WIXSTDBA_VARIABLE_SUPPRESS_OPTIONS_UI, 1);
2497 BalExitOnFailure(hr, "Failed to set '%ls' variable.", WIXSTDBA_VARIABLE_SUPPRESS_OPTIONS_UI);
2498 }
2499 BalExitOnFailure(hr, "Failed to get SuppressOptionsUI value.");
2500
2501 dwBool = 0;
2502 hr = XmlGetAttributeNumber(pNode, L"SuppressDowngradeFailure", &dwBool);
2503 if (S_FALSE == hr)
2504 {
2505 hr = S_OK;
2506 }
2507 else if (SUCCEEDED(hr))
2508 {
2509 m_fSuppressDowngradeFailure = 0 < dwBool;
2510 }
2511 BalExitOnFailure(hr, "Failed to get SuppressDowngradeFailure value.");
2512
2513 dwBool = 0;
2514 hr = XmlGetAttributeNumber(pNode, L"SuppressRepair", &dwBool);
2515 if (S_FALSE == hr)
2516 {
2517 hr = S_OK;
2518 }
2519 else if (SUCCEEDED(hr))
2520 {
2521 m_fSuppressRepair = 0 < dwBool;
2522 }
2523 BalExitOnFailure(hr, "Failed to get SuppressRepair value.");
2524
2525 hr = XmlGetAttributeNumber(pNode, L"ShowVersion", &dwBool);
2526 if (S_FALSE == hr)
2527 {
2528 hr = S_OK;
2529 }
2530 else if (SUCCEEDED(hr) && dwBool)
2531 {
2532 hr = BalSetNumericVariable(WIXSTDBA_VARIABLE_SHOW_VERSION, 1);
2533 BalExitOnFailure(hr, "Failed to set '%ls' variable.", WIXSTDBA_VARIABLE_SHOW_VERSION);
2534 }
2535 BalExitOnFailure(hr, "Failed to get ShowVersion value.");
2536
2537 hr = XmlGetAttributeNumber(pNode, L"SupportCacheOnly", &dwBool);
2538 if (S_FALSE == hr)
2539 {
2540 hr = S_OK;
2541 }
2542 else if (SUCCEEDED(hr))
2543 {
2544 m_fSupportCacheOnly = 0 < dwBool;
2545 }
2546 BalExitOnFailure(hr, "Failed to get SupportCacheOnly value.");
2547
2548 LExit:
2549 ReleaseObject(pNode);
2550 return hr;
2551 }
2552
2553 HRESULT GetPackageInfo(
2554 __in_z LPCWSTR wzPackageId,
2555 __out WIXSTDBA_PACKAGE_INFO** ppPackageInfo,
2556 __out BAL_INFO_PACKAGE** ppPackage
2557 )
2558 {
2559 HRESULT hr = E_NOTFOUND;
2560 WIXSTDBA_PACKAGE_INFO* pPackageInfo = NULL;
2561 BAL_INFO_PACKAGE* pPackage = NULL;
2562
2563 Assert(wzPackageId && *wzPackageId);
2564 Assert(ppPackage);
2565 Assert(ppPackageInfo);
2566
2567 hr = BalInfoFindPackageById(&m_Bundle.packages, wzPackageId, &pPackage);
2568 if (E_NOTFOUND != hr)
2569 {
2570 ExitOnFailure(hr, "Failed trying to find the requested package.");
2571
2572 pPackageInfo = reinterpret_cast<WIXSTDBA_PACKAGE_INFO*>(pPackage->pvCustomData);
2573 }
2574
2575 *ppPackageInfo = pPackageInfo;
2576 *ppPackage = pPackage;
2577
2578 LExit:
2579 return hr;
2580 }
2581
2582
2583 //
2584 // Get the file version of the bootstrapper and record in bootstrapper log file
2585 //
2586 HRESULT GetBundleFileVersion()
2587 {
2588 HRESULT hr = S_OK;
2589 ULARGE_INTEGER uliVersion = { };
2590 LPWSTR sczCurrentPath = NULL;
2591 VERUTIL_VERSION* pVersion = NULL;
2592
2593 hr = PathForCurrentProcess(&sczCurrentPath, NULL);
2594 BalExitOnFailure(hr, "Failed to get bundle path.");
2595
2596 hr = FileVersion(sczCurrentPath, &uliVersion.HighPart, &uliVersion.LowPart);
2597 BalExitOnFailure(hr, "Failed to get bundle file version.");
2598
2599 hr = VerVersionFromQword(uliVersion.QuadPart, &pVersion);
2600 BalExitOnFailure(hr, "Failed to create bundle file version.");
2601
2602 hr = m_pEngine->SetVariableVersion(WIXSTDBA_VARIABLE_BUNDLE_FILE_VERSION, pVersion->sczVersion);
2603 BalExitOnFailure(hr, "Failed to set WixBundleFileVersion variable.");
2604
2605 LExit:
2606 ReleaseVerutilVersion(pVersion);
2607 ReleaseStr(sczCurrentPath);
2608
2609 return hr;
2610 }
2611
2612
2613 //
2614 // CreateMainWindow - creates the main install window.
2615 //
2616 HRESULT CreateMainWindow()
2617 {
2618 HRESULT hr = S_OK;
2619 HICON hIcon = reinterpret_cast<HICON>(m_pTheme->hIcon);
2620 WNDCLASSW wc = { };
2621 DWORD dwWindowStyle = 0;
2622 int x = CW_USEDEFAULT;
2623 int y = CW_USEDEFAULT;
2624 POINT ptCursor = { };
2625
2626 // If the theme did not provide an icon, try using the icon from the bundle engine.
2627 if (!hIcon)
2628 {
2629 HMODULE hBootstrapperEngine = ::GetModuleHandleW(NULL);
2630 if (hBootstrapperEngine)
2631 {
2632 hIcon = ::LoadIconW(hBootstrapperEngine, MAKEINTRESOURCEW(1));
2633 }
2634 }
2635
2636 // Register the window class and create the window.
2637 wc.lpfnWndProc = CWixStandardBootstrapperApplication::WndProc;
2638 wc.hInstance = m_hModule;
2639 wc.hIcon = hIcon;
2640 wc.hCursor = ::LoadCursorW(NULL, (LPCWSTR)IDC_ARROW);
2641 wc.hbrBackground = m_pTheme->rgFonts[m_pTheme->dwFontId].hBackground;
2642 wc.lpszMenuName = NULL;
2643 wc.lpszClassName = WIXSTDBA_WINDOW_CLASS;
2644 if (!::RegisterClassW(&wc))
2645 {
2646 ExitWithLastError(hr, "Failed to register window.");
2647 }
2648
2649 m_fRegistered = TRUE;
2650
2651 // Calculate the window style based on the theme style and command display value.
2652 dwWindowStyle = m_pTheme->dwStyle;
2653 if (BOOTSTRAPPER_DISPLAY_NONE >= m_command.display)
2654 {
2655 dwWindowStyle &= ~WS_VISIBLE;
2656 }
2657
2658 // Don't show the window if there is a splash screen (it will be made visible when the splash screen is hidden)
2659 if (::IsWindow(m_command.hwndSplashScreen))
2660 {
2661 dwWindowStyle &= ~WS_VISIBLE;
2662 }
2663
2664 // Center the window on the monitor with the mouse.
2665 if (::GetCursorPos(&ptCursor))
2666 {
2667 x = ptCursor.x;
2668 y = ptCursor.y;
2669 }
2670
2671 hr = ThemeCreateParentWindow(m_pTheme, 0, wc.lpszClassName, m_pTheme->sczCaption, dwWindowStyle, x, y, HWND_DESKTOP, m_hModule, this, THEME_WINDOW_INITIAL_POSITION_CENTER_MONITOR_FROM_COORDINATES, &m_hWnd);
2672 ExitOnFailure(hr, "Failed to create window.");
2673
2674 hr = S_OK;
2675
2676 LExit:
2677 return hr;
2678 }
2679
2680
2681 //
2682 // InitializeTaskbarButton - initializes taskbar button for progress.
2683 //
2684 void InitializeTaskbarButton()
2685 {
2686 HRESULT hr = S_OK;
2687
2688 hr = ::CoCreateInstance(CLSID_TaskbarList, NULL, CLSCTX_ALL, __uuidof(ITaskbarList3), reinterpret_cast<LPVOID*>(&m_pTaskbarList));
2689 if (REGDB_E_CLASSNOTREG == hr) // not supported before Windows 7
2690 {
2691 ExitFunction1(hr = S_OK);
2692 }
2693 BalExitOnFailure(hr, "Failed to create ITaskbarList3. Continuing.");
2694
2695 m_uTaskbarButtonCreatedMessage = ::RegisterWindowMessageW(L"TaskbarButtonCreated");
2696 BalExitOnNullWithLastError(m_uTaskbarButtonCreatedMessage, hr, "Failed to get TaskbarButtonCreated message. Continuing.");
2697
2698 LExit:
2699 return;
2700 }
2701
2702 //
2703 // DestroyMainWindow - clean up all the window registration.
2704 //
2705 void DestroyMainWindow()
2706 {
2707 if (::IsWindow(m_hWnd))
2708 {
2709 ::DestroyWindow(m_hWnd);
2710 m_hWnd = NULL;
2711 m_fTaskbarButtonOK = FALSE;
2712 }
2713
2714 if (m_fRegistered)
2715 {
2716 ::UnregisterClassW(WIXSTDBA_WINDOW_CLASS, m_hModule);
2717 m_fRegistered = FALSE;
2718 }
2719 }
2720
2721
2722 //
2723 // UninitializeTaskbarButton - clean up the taskbar registration.
2724 //
2725 void UninitializeTaskbarButton()
2726 {
2727 m_fTaskbarButtonOK = FALSE;
2728 ReleaseNullObject(m_pTaskbarList);
2729 }
2730
2731
2732 static LRESULT CallDefaultWndProc(
2733 __in CWixStandardBootstrapperApplication* pBA,
2734 __in HWND hWnd,
2735 __in UINT uMsg,
2736 __in WPARAM wParam,
2737 __in LPARAM lParam
2738 )
2739 {
2740 LRESULT lres = NULL;
2741 THEME* pTheme = NULL;
2742 HRESULT hr = S_OK;
2743 BA_FUNCTIONS_WNDPROC_ARGS wndProcArgs = { };
2744 BA_FUNCTIONS_WNDPROC_RESULTS wndProcResults = { };
2745
2746 if (pBA)
2747 {
2748 pTheme = pBA->m_pTheme;
2749
2750 if (pBA->m_pfnBAFunctionsProc)
2751 {
2752 wndProcArgs.cbSize = sizeof(wndProcArgs);
2753 wndProcArgs.pTheme = pTheme;
2754 wndProcArgs.hWnd = hWnd;
2755 wndProcArgs.uMsg = uMsg;
2756 wndProcArgs.wParam = wParam;
2757 wndProcArgs.lParam = lParam;
2758 wndProcResults.cbSize = sizeof(wndProcResults);
2759
2760 hr = pBA->m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_WNDPROC, &wndProcArgs, &wndProcResults, pBA->m_pvBAFunctionsProcContext);
2761 if (E_NOTIMPL != hr)
2762 {
2763 lres = wndProcResults.lres;
2764 ExitFunction();
2765 }
2766 }
2767 }
2768
2769 lres = ThemeDefWindowProc(pTheme, hWnd, uMsg, wParam, lParam);
2770
2771 LExit:
2772 return lres;
2773 }
2774
2775 //
2776 // WndProc - standard windows message handler.
2777 //
2778 static LRESULT CALLBACK WndProc(
2779 __in HWND hWnd,
2780 __in UINT uMsg,
2781 __in WPARAM wParam,
2782 __in LPARAM lParam
2783 )
2784 {
2785#pragma warning(suppress:4312)
2786 CWixStandardBootstrapperApplication* pBA = reinterpret_cast<CWixStandardBootstrapperApplication*>(::GetWindowLongPtrW(hWnd, GWLP_USERDATA));
2787 BOOL fCancel = FALSE;
2788
2789 switch (uMsg)
2790 {
2791 case WM_NCCREATE:
2792 {
2793 LPCREATESTRUCT lpcs = reinterpret_cast<LPCREATESTRUCT>(lParam);
2794 pBA = reinterpret_cast<CWixStandardBootstrapperApplication*>(lpcs->lpCreateParams);
2795#pragma warning(suppress:4244)
2796 ::SetWindowLongPtrW(hWnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(pBA));
2797 }
2798 break;
2799
2800 case WM_NCDESTROY:
2801 {
2802 LRESULT lres = CallDefaultWndProc(pBA, hWnd, uMsg, wParam, lParam);
2803 ::SetWindowLongPtrW(hWnd, GWLP_USERDATA, 0);
2804 ::PostQuitMessage(0);
2805 return lres;
2806 }
2807
2808 case WM_CREATE:
2809 if (!pBA->OnCreate(hWnd))
2810 {
2811 return -1;
2812 }
2813 break;
2814
2815 case WM_QUERYENDSESSION:
2816 fCancel = true;
2817 pBA->OnSystemShutdown(static_cast<DWORD>(lParam), &fCancel);
2818 return !fCancel;
2819
2820 case WM_CLOSE:
2821 // If the user chose not to close, do *not* let the default window proc handle the message.
2822 if (!pBA->OnClose())
2823 {
2824 return 0;
2825 }
2826 break;
2827
2828 case WM_WIXSTDBA_SHOW_HELP:
2829 pBA->OnShowHelp();
2830 return 0;
2831
2832 case WM_WIXSTDBA_DETECT_PACKAGES:
2833 pBA->OnDetect();
2834 return 0;
2835
2836 case WM_WIXSTDBA_PLAN_PACKAGES:
2837 pBA->OnPlan(static_cast<BOOTSTRAPPER_ACTION>(lParam));
2838 return 0;
2839
2840 case WM_WIXSTDBA_APPLY_PACKAGES:
2841 pBA->OnApply();
2842 return 0;
2843
2844 case WM_WIXSTDBA_CHANGE_STATE:
2845 pBA->OnChangeState(static_cast<WIXSTDBA_STATE>(lParam));
2846 return 0;
2847
2848 case WM_WIXSTDBA_SHOW_FAILURE:
2849 pBA->OnShowFailure();
2850 return 0;
2851
2852 case WM_COMMAND:
2853 switch (HIWORD(wParam))
2854 {
2855 case BN_CLICKED:
2856 switch (LOWORD(wParam))
2857 {
2858 case WIXSTDBA_CONTROL_EULA_ACCEPT_CHECKBOX:
2859 pBA->OnClickAcceptCheckbox();
2860 return 0;
2861
2862 case WIXSTDBA_CONTROL_INSTALL_BUTTON:
2863 pBA->OnClickInstallButton();
2864 return 0;
2865
2866 case WIXSTDBA_CONTROL_REPAIR_BUTTON:
2867 pBA->OnClickRepairButton();
2868 return 0;
2869
2870 case WIXSTDBA_CONTROL_UNINSTALL_BUTTON:
2871 pBA->OnClickUninstallButton();
2872 return 0;
2873
2874 case WIXSTDBA_CONTROL_LAUNCH_BUTTON:
2875 pBA->OnClickLaunchButton();
2876 return 0;
2877
2878 case WIXSTDBA_CONTROL_SUCCESS_RESTART_BUTTON: __fallthrough;
2879 case WIXSTDBA_CONTROL_FAILURE_RESTART_BUTTON:
2880 pBA->OnClickRestartButton();
2881 return 0;
2882
2883 case WIXSTDBA_CONTROL_PROGRESS_CANCEL_BUTTON:
2884 pBA->OnClickCloseButton();
2885 return 0;
2886 }
2887 break;
2888 }
2889 break;
2890
2891 case WM_NOTIFY:
2892 if (lParam)
2893 {
2894 LPNMHDR pnmhdr = reinterpret_cast<LPNMHDR>(lParam);
2895 switch (pnmhdr->code)
2896 {
2897 case NM_CLICK: __fallthrough;
2898 case NM_RETURN:
2899 switch (static_cast<DWORD>(pnmhdr->idFrom))
2900 {
2901 case WIXSTDBA_CONTROL_EULA_LINK:
2902 pBA->OnClickEulaLink();
2903 return 1;
2904 case WIXSTDBA_CONTROL_FAILURE_LOGFILE_LINK:
2905 pBA->OnClickLogFileLink();
2906 return 1;
2907 }
2908 }
2909 }
2910 break;
2911 }
2912
2913 if (pBA && pBA->m_pTaskbarList && uMsg == pBA->m_uTaskbarButtonCreatedMessage)
2914 {
2915 pBA->m_fTaskbarButtonOK = TRUE;
2916 return 0;
2917 }
2918
2919 return CallDefaultWndProc(pBA, hWnd, uMsg, wParam, lParam);
2920 }
2921
2922
2923 //
2924 // OnCreate - finishes loading the theme.
2925 //
2926 BOOL OnCreate(
2927 __in HWND /*hWnd*/
2928 )
2929 {
2930 HRESULT hr = S_OK;
2931 LPWSTR sczLicenseFormatted = NULL;
2932 LPWSTR sczLicensePath = NULL;
2933 LPWSTR sczLicenseDirectory = NULL;
2934 LPWSTR sczLicenseFilename = NULL;
2935 BA_FUNCTIONS_ONTHEMELOADED_ARGS themeLoadedArgs = { };
2936 BA_FUNCTIONS_ONTHEMELOADED_RESULTS themeLoadedResults = { };
2937
2938 hr = ThemeLoadControls(m_pTheme, vrgInitControls, countof(vrgInitControls));
2939 BalExitOnFailure(hr, "Failed to load theme controls.");
2940
2941 C_ASSERT(COUNT_WIXSTDBA_PAGE == countof(vrgwzPageNames));
2942 C_ASSERT(countof(m_rgdwPageIds) == countof(vrgwzPageNames));
2943
2944 ThemeGetPageIds(m_pTheme, vrgwzPageNames, m_rgdwPageIds, countof(m_rgdwPageIds));
2945
2946 // Load the RTF EULA control with text if the control exists.
2947 if (ThemeControlExists(m_pTheme, WIXSTDBA_CONTROL_EULA_RICHEDIT))
2948 {
2949 hr = (m_sczLicenseFile && *m_sczLicenseFile) ? S_OK : E_INVALIDDATA;
2950 if (SUCCEEDED(hr))
2951 {
2952 hr = StrAllocString(&sczLicenseFormatted, m_sczLicenseFile, 0);
2953 if (SUCCEEDED(hr))
2954 {
2955 hr = LocLocalizeString(m_pWixLoc, &sczLicenseFormatted);
2956 if (SUCCEEDED(hr))
2957 {
2958 // Assume there is no hidden variables to be formatted
2959 // so don't worry about securely freeing it.
2960 hr = BalFormatString(sczLicenseFormatted, &sczLicenseFormatted);
2961 if (SUCCEEDED(hr))
2962 {
2963 hr = PathRelativeToModule(&sczLicensePath, sczLicenseFormatted, m_hModule);
2964 if (SUCCEEDED(hr))
2965 {
2966 hr = PathGetDirectory(sczLicensePath, &sczLicenseDirectory);
2967 if (SUCCEEDED(hr))
2968 {
2969 hr = StrAllocString(&sczLicenseFilename, PathFile(sczLicenseFormatted), 0);
2970 if (SUCCEEDED(hr))
2971 {
2972 hr = LocProbeForFile(sczLicenseDirectory, sczLicenseFilename, m_sczLanguage, &sczLicensePath);
2973 if (SUCCEEDED(hr))
2974 {
2975 hr = ThemeLoadRichEditFromFile(m_pTheme, WIXSTDBA_CONTROL_EULA_RICHEDIT, sczLicensePath, m_hModule);
2976 }
2977 }
2978 }
2979 }
2980 }
2981 }
2982 }
2983 }
2984
2985 if (FAILED(hr))
2986 {
2987 BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Failed to load file into license richedit control from path '%ls' manifest value: %ls", sczLicensePath, m_sczLicenseFile);
2988 hr = S_OK;
2989 }
2990 }
2991
2992 if (m_pfnBAFunctionsProc)
2993 {
2994 themeLoadedArgs.cbSize = sizeof(themeLoadedArgs);
2995 themeLoadedArgs.pTheme = m_pTheme;
2996 themeLoadedArgs.pWixLoc = m_pWixLoc;
2997 themeLoadedResults.cbSize = sizeof(themeLoadedResults);
2998 hr = m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONTHEMELOADED, &themeLoadedArgs, &themeLoadedResults, m_pvBAFunctionsProcContext);
2999 BalExitOnFailure(hr, "BAFunctions OnThemeLoaded failed.");
3000 }
3001
3002 LExit:
3003 ReleaseStr(sczLicenseFilename);
3004 ReleaseStr(sczLicenseDirectory);
3005 ReleaseStr(sczLicensePath);
3006 ReleaseStr(sczLicenseFormatted);
3007
3008 return SUCCEEDED(hr);
3009 }
3010
3011
3012 //
3013 // OnShowFailure - display the failure page.
3014 //
3015 void OnShowFailure()
3016 {
3017 SetState(WIXSTDBA_STATE_FAILED, S_OK);
3018
3019 // If the UI should be visible, display it now and hide the splash screen
3020 if (BOOTSTRAPPER_DISPLAY_NONE < m_command.display)
3021 {
3022 ::ShowWindow(m_pTheme->hwndParent, SW_SHOW);
3023 }
3024
3025 m_pEngine->CloseSplashScreen();
3026
3027 return;
3028 }
3029
3030
3031 //
3032 // OnShowHelp - display the help page.
3033 //
3034 void OnShowHelp()
3035 {
3036 SetState(WIXSTDBA_STATE_HELP, S_OK);
3037
3038 // If the UI should be visible, display it now and hide the splash screen
3039 if (BOOTSTRAPPER_DISPLAY_NONE < m_command.display)
3040 {
3041 ::ShowWindow(m_pTheme->hwndParent, SW_SHOW);
3042 }
3043
3044 m_pEngine->CloseSplashScreen();
3045
3046 return;
3047 }
3048
3049
3050 //
3051 // OnDetect - start the processing of packages.
3052 //
3053 void OnDetect()
3054 {
3055 HRESULT hr = S_OK;
3056
3057 SetState(WIXSTDBA_STATE_DETECTING, hr);
3058
3059 // If the UI should be visible, display it now and hide the splash screen
3060 if (BOOTSTRAPPER_DISPLAY_NONE < m_command.display)
3061 {
3062 ::ShowWindow(m_pTheme->hwndParent, SW_SHOW);
3063 }
3064
3065 m_pEngine->CloseSplashScreen();
3066
3067 // Tell the core we're ready for the packages to be processed now.
3068 hr = m_pEngine->Detect();
3069 BalExitOnFailure(hr, "Failed to start detecting chain.");
3070
3071 LExit:
3072 if (FAILED(hr))
3073 {
3074 SetState(WIXSTDBA_STATE_DETECTING, hr);
3075 }
3076
3077 return;
3078 }
3079
3080
3081 //
3082 // OnPlan - plan the detected changes.
3083 //
3084 void OnPlan(
3085 __in BOOTSTRAPPER_ACTION action
3086 )
3087 {
3088 HRESULT hr = S_OK;
3089
3090 m_plannedAction = action;
3091
3092 // If we are going to apply a downgrade, bail.
3093 if (m_fDowngrading && BOOTSTRAPPER_ACTION_UNINSTALL < action)
3094 {
3095 if (m_fSuppressDowngradeFailure)
3096 {
3097 BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "A newer version of this product is installed but downgrade failure has been suppressed; continuing...");
3098 }
3099 else
3100 {
3101 hr = HRESULT_FROM_WIN32(ERROR_PRODUCT_VERSION);
3102 BalExitOnFailure(hr, "Cannot install a product when a newer version is installed.");
3103 }
3104 }
3105
3106 SetState(WIXSTDBA_STATE_PLANNING, hr);
3107
3108 hr = m_pEngine->Plan(action);
3109 BalExitOnFailure(hr, "Failed to start planning packages.");
3110
3111 LExit:
3112 if (FAILED(hr))
3113 {
3114 SetState(WIXSTDBA_STATE_PLANNING, hr);
3115 }
3116
3117 return;
3118 }
3119
3120
3121 //
3122 // OnApply - apply the packages.
3123 //
3124 void OnApply()
3125 {
3126 HRESULT hr = S_OK;
3127
3128 SetState(WIXSTDBA_STATE_APPLYING, hr);
3129 SetProgressState(hr);
3130 SetTaskbarButtonProgress(0);
3131
3132 hr = m_pEngine->Apply(m_hWnd);
3133 BalExitOnFailure(hr, "Failed to start applying packages.");
3134
3135 ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_PROGRESS_CANCEL_BUTTON, TRUE); // ensure the cancel button is enabled before starting.
3136
3137 LExit:
3138 if (FAILED(hr))
3139 {
3140 SetState(WIXSTDBA_STATE_APPLYING, hr);
3141 }
3142
3143 return;
3144 }
3145
3146
3147 //
3148 // OnChangeState - change state.
3149 //
3150 void OnChangeState(
3151 __in WIXSTDBA_STATE state
3152 )
3153 {
3154 WIXSTDBA_STATE stateOld = m_state;
3155 DWORD dwOldPageId = 0;
3156 DWORD dwNewPageId = 0;
3157 LPWSTR sczText = NULL;
3158 LPWSTR sczUnformattedText = NULL;
3159 LPWSTR sczControlState = NULL;
3160 LPWSTR sczControlName = NULL;
3161
3162 m_state = state;
3163
3164 // If our install is at the end (success or failure) and we're not showing full UI or
3165 // we successfully installed the prerequisite then exit (prompt for restart if required).
3166 if ((WIXSTDBA_STATE_APPLIED <= m_state && BOOTSTRAPPER_DISPLAY_FULL > m_command.display) ||
3167 (WIXSTDBA_STATE_APPLIED == m_state && m_fPrereq))
3168 {
3169 // If a restart was required but we were not automatically allowed to
3170 // accept the reboot then do the prompt.
3171 if (m_fRestartRequired && !m_fAllowRestart)
3172 {
3173 StrAllocFromError(&sczUnformattedText, HRESULT_FROM_WIN32(ERROR_SUCCESS_REBOOT_REQUIRED), NULL);
3174
3175 int nResult = ::MessageBoxW(m_hWnd, sczUnformattedText ? sczUnformattedText : L"The requested operation is successful. Changes will not be effective until the system is rebooted.", m_pTheme->sczCaption, MB_ICONEXCLAMATION | MB_OKCANCEL);
3176 m_fAllowRestart = (IDOK == nResult);
3177 }
3178
3179 // Quietly exit.
3180 ::PostMessageW(m_hWnd, WM_CLOSE, 0, 0);
3181 }
3182 else // try to change the pages.
3183 {
3184 DeterminePageId(stateOld, &dwOldPageId);
3185 DeterminePageId(m_state, &dwNewPageId);
3186
3187 if (dwOldPageId != dwNewPageId)
3188 {
3189 // Enable disable controls per-page.
3190 if (m_rgdwPageIds[WIXSTDBA_PAGE_INSTALL] == dwNewPageId) // on the "Install" page, ensure the install button is enabled/disabled correctly.
3191 {
3192 LONGLONG llElevated = 0;
3193 if (m_Bundle.fPerMachine)
3194 {
3195 BalGetNumericVariable(WIXBUNDLE_VARIABLE_ELEVATED, &llElevated);
3196 }
3197 ThemeControlElevates(m_pTheme, WIXSTDBA_CONTROL_INSTALL_BUTTON, (m_Bundle.fPerMachine && !llElevated));
3198
3199 // If the EULA control exists, show it only if a license URL is provided as well.
3200 if (ThemeControlExists(m_pTheme, WIXSTDBA_CONTROL_EULA_LINK))
3201 {
3202 BOOL fEulaLink = (m_sczLicenseUrl && *m_sczLicenseUrl);
3203 ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_EULA_LINK, fEulaLink);
3204 ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_EULA_ACCEPT_CHECKBOX, fEulaLink);
3205 }
3206
3207 BOOL fAcceptedLicense = !ThemeControlExists(m_pTheme, WIXSTDBA_CONTROL_EULA_ACCEPT_CHECKBOX) || !ThemeControlEnabled(m_pTheme, WIXSTDBA_CONTROL_EULA_ACCEPT_CHECKBOX) || ThemeIsControlChecked(m_pTheme, WIXSTDBA_CONTROL_EULA_ACCEPT_CHECKBOX);
3208 ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_INSTALL_BUTTON, fAcceptedLicense);
3209 }
3210 else if (m_rgdwPageIds[WIXSTDBA_PAGE_MODIFY] == dwNewPageId)
3211 {
3212 ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_REPAIR_BUTTON, !m_fSuppressRepair);
3213 }
3214 else if (m_rgdwPageIds[WIXSTDBA_PAGE_SUCCESS] == dwNewPageId) // on the "Success" page, check if the restart or launch button should be enabled.
3215 {
3216 BOOL fShowRestartButton = FALSE;
3217 BOOL fLaunchTargetExists = FALSE;
3218 if (m_fRestartRequired)
3219 {
3220 if (BOOTSTRAPPER_RESTART_PROMPT == m_command.restart)
3221 {
3222 fShowRestartButton = TRUE;
3223 }
3224 }
3225 else if (ThemeControlExists(m_pTheme, WIXSTDBA_CONTROL_LAUNCH_BUTTON))
3226 {
3227 fLaunchTargetExists = BalVariableExists(WIXSTDBA_VARIABLE_LAUNCH_TARGET_PATH);
3228 }
3229
3230 ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_LAUNCH_BUTTON, fLaunchTargetExists && BOOTSTRAPPER_ACTION_UNINSTALL < m_plannedAction);
3231 ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_SUCCESS_RESTART_BUTTON, fShowRestartButton);
3232 }
3233 else if (m_rgdwPageIds[WIXSTDBA_PAGE_FAILURE] == dwNewPageId) // on the "Failure" page, show error message and check if the restart button should be enabled.
3234 {
3235 BOOL fShowLogLink = (m_Bundle.sczLogVariable && *m_Bundle.sczLogVariable); // if there is a log file variable then we'll assume the log file exists.
3236 BOOL fShowErrorMessage = FALSE;
3237 BOOL fShowRestartButton = FALSE;
3238
3239 if (FAILED(m_hrFinal))
3240 {
3241 // If we know the failure message, use that.
3242 if (m_sczFailedMessage && *m_sczFailedMessage)
3243 {
3244 StrAllocString(&sczUnformattedText, m_sczFailedMessage, 0);
3245 }
3246 else if (E_MBAHOST_NET452_ON_WIN7RTM == m_hrFinal)
3247 {
3248 HRESULT hr = StrAllocString(&sczUnformattedText, L"#(loc.NET452WIN7RTMErrorMessage)", 0);
3249 if (FAILED(hr))
3250 {
3251 BalLogError(hr, "Failed to initialize NET452WIN7RTMErrorMessage loc identifier.");
3252 }
3253 else
3254 {
3255 hr = LocLocalizeString(m_pWixLoc, &sczUnformattedText);
3256 if (FAILED(hr))
3257 {
3258 BalLogError(hr, "Failed to localize NET452WIN7RTMErrorMessage: %ls", sczUnformattedText);
3259 ReleaseNullStr(sczUnformattedText);
3260 }
3261 }
3262 }
3263 else if (E_DNCHOST_SCD_RUNTIME_FAILURE == m_hrFinal)
3264 {
3265 HRESULT hr = StrAllocString(&sczUnformattedText, L"#(loc.SCDRUNTIMEFAILUREErrorMessage)", 0);
3266 if (FAILED(hr))
3267 {
3268 BalLogError(hr, "Failed to initialize SCDRUNTIMEFAILUREErrorMessage loc identifier.");
3269 }
3270 else
3271 {
3272 hr = LocLocalizeString(m_pWixLoc, &sczUnformattedText);
3273 if (FAILED(hr))
3274 {
3275 BalLogError(hr, "Failed to localize SCDRUNTIMEFAILUREErrorMessage: %ls", sczUnformattedText);
3276 ReleaseNullStr(sczUnformattedText);
3277 }
3278 }
3279 }
3280 else // try to get the error message from the error code.
3281 {
3282 StrAllocFromError(&sczUnformattedText, m_hrFinal, NULL);
3283 if (!sczUnformattedText || !*sczUnformattedText)
3284 {
3285 StrAllocFromError(&sczUnformattedText, E_FAIL, NULL);
3286 }
3287 }
3288
3289 if (E_WIXSTDBA_CONDITION_FAILED == m_hrFinal)
3290 {
3291 if (sczUnformattedText)
3292 {
3293 StrAllocString(&sczText, sczUnformattedText, 0);
3294 }
3295 }
3296 else if (E_MBAHOST_NET452_ON_WIN7RTM == m_hrFinal)
3297 {
3298 if (sczUnformattedText)
3299 {
3300 BalFormatString(sczUnformattedText, &sczText);
3301 }
3302 }
3303 else if (E_DNCHOST_SCD_RUNTIME_FAILURE == m_hrFinal)
3304 {
3305 if (sczUnformattedText)
3306 {
3307 BalFormatString(sczUnformattedText, &sczText);
3308 }
3309 }
3310 else
3311 {
3312 StrAllocFormatted(&sczText, L"0x%08x - %ls", m_hrFinal, sczUnformattedText);
3313 }
3314
3315 ThemeSetTextControl(m_pTheme, WIXSTDBA_CONTROL_FAILURE_MESSAGE_TEXT, sczText);
3316 fShowErrorMessage = TRUE;
3317 }
3318
3319 if (m_fRestartRequired)
3320 {
3321 if (BOOTSTRAPPER_RESTART_PROMPT == m_command.restart)
3322 {
3323 fShowRestartButton = TRUE;
3324 }
3325 }
3326
3327 ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_FAILURE_LOGFILE_LINK, fShowLogLink);
3328 ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_FAILURE_MESSAGE_TEXT, fShowErrorMessage);
3329 ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_FAILURE_RESTART_BUTTON, fShowRestartButton);
3330 }
3331
3332 HRESULT hr = ThemeShowPage(m_pTheme, dwOldPageId, SW_HIDE);
3333 if (FAILED(hr))
3334 {
3335 BalLogError(hr, "Failed to hide page: %u", dwOldPageId);
3336 }
3337
3338 hr = ThemeShowPage(m_pTheme, dwNewPageId, SW_SHOW);
3339 if (FAILED(hr))
3340 {
3341 BalLogError(hr, "Failed to show page: %u", dwOldPageId);
3342 }
3343
3344 // On the install page set the focus to the install button or the next enabled control if install is disabled.
3345 if (m_rgdwPageIds[WIXSTDBA_PAGE_INSTALL] == dwNewPageId)
3346 {
3347 ThemeSetFocus(m_pTheme, WIXSTDBA_CONTROL_INSTALL_BUTTON);
3348 }
3349 }
3350 }
3351
3352 ReleaseStr(sczText);
3353 ReleaseStr(sczUnformattedText);
3354 ReleaseStr(sczControlState);
3355 ReleaseStr(sczControlName);
3356 }
3357
3358
3359 //
3360 // OnClose - called when the window is trying to be closed.
3361 //
3362 BOOL OnClose()
3363 {
3364 BOOL fClose = FALSE;
3365 BOOL fCancel = FALSE;
3366
3367 // If we've already succeeded or failed or showing the help page, just close (prompts are annoying if the bootstrapper is done).
3368 if (WIXSTDBA_STATE_APPLIED <= m_state || WIXSTDBA_STATE_HELP == m_state)
3369 {
3370 fClose = TRUE;
3371 }
3372 else // prompt the user or force the cancel if there is no UI.
3373 {
3374 ::EnterCriticalSection(&m_csShowingInternalUiThisPackage);
3375 fClose = PromptCancel(
3376 m_hWnd,
3377 BOOTSTRAPPER_DISPLAY_FULL != m_command.display || m_fShowingInternalUiThisPackage,
3378 m_sczConfirmCloseMessage ? m_sczConfirmCloseMessage : L"Are you sure you want to cancel?",
3379 m_pTheme->sczCaption);
3380 ::LeaveCriticalSection(&m_csShowingInternalUiThisPackage);
3381
3382 fCancel = fClose;
3383 }
3384
3385 // If we're doing progress then we never close, we just cancel to let rollback occur.
3386 if (WIXSTDBA_STATE_APPLYING <= m_state && WIXSTDBA_STATE_APPLIED > m_state)
3387 {
3388 // If we canceled, disable cancel button since clicking it again is silly.
3389 if (fClose)
3390 {
3391 ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_PROGRESS_CANCEL_BUTTON, FALSE);
3392 }
3393
3394 fClose = FALSE;
3395 }
3396
3397 if (fClose)
3398 {
3399 DWORD dwCurrentPageId = 0;
3400 DeterminePageId(m_state, &dwCurrentPageId);
3401
3402 // Hide the current page to let thmutil do its thing with variables.
3403 ThemeShowPageEx(m_pTheme, dwCurrentPageId, SW_HIDE, fCancel ? THEME_SHOW_PAGE_REASON_CANCEL : THEME_SHOW_PAGE_REASON_DEFAULT);
3404 }
3405
3406 return fClose;
3407 }
3408
3409
3410 //
3411 // OnClickAcceptCheckbox - allow the install to continue.
3412 //
3413 void OnClickAcceptCheckbox()
3414 {
3415 BOOL fAcceptedLicense = ThemeIsControlChecked(m_pTheme, WIXSTDBA_CONTROL_EULA_ACCEPT_CHECKBOX);
3416 ThemeControlEnable(m_pTheme, WIXSTDBA_CONTROL_INSTALL_BUTTON, fAcceptedLicense);
3417 }
3418
3419
3420 //
3421 // OnClickInstallButton - start the install by planning the packages.
3422 //
3423 void OnClickInstallButton()
3424 {
3425 this->OnPlan(BOOTSTRAPPER_ACTION_INSTALL);
3426 }
3427
3428
3429 //
3430 // OnClickRepairButton - start the repair.
3431 //
3432 void OnClickRepairButton()
3433 {
3434 this->OnPlan(BOOTSTRAPPER_ACTION_REPAIR);
3435 }
3436
3437
3438 //
3439 // OnClickUninstallButton - start the uninstall.
3440 //
3441 void OnClickUninstallButton()
3442 {
3443 this->OnPlan(BOOTSTRAPPER_ACTION_UNINSTALL);
3444 }
3445
3446
3447 //
3448 // OnClickCloseButton - close the application.
3449 //
3450 void OnClickCloseButton()
3451 {
3452 ::SendMessageW(m_hWnd, WM_CLOSE, 0, 0);
3453 }
3454
3455
3456 //
3457 // OnClickEulaLink - show the end user license agreement.
3458 //
3459 void OnClickEulaLink()
3460 {
3461 HRESULT hr = S_OK;
3462 LPWSTR sczLicenseUrl = NULL;
3463 LPWSTR sczLicensePath = NULL;
3464 LPWSTR sczLicenseDirectory = NULL;
3465 LPWSTR sczLicenseFilename = NULL;
3466 URI_PROTOCOL protocol = URI_PROTOCOL_UNKNOWN;
3467
3468 hr = StrAllocString(&sczLicenseUrl, m_sczLicenseUrl, 0);
3469 BalExitOnFailure(hr, "Failed to copy license URL: %ls", m_sczLicenseUrl);
3470
3471 hr = LocLocalizeString(m_pWixLoc, &sczLicenseUrl);
3472 BalExitOnFailure(hr, "Failed to localize license URL: %ls", m_sczLicenseUrl);
3473
3474 // Assume there is no hidden variables to be formatted
3475 // so don't worry about securely freeing it.
3476 hr = BalFormatString(sczLicenseUrl, &sczLicenseUrl);
3477 BalExitOnFailure(hr, "Failed to get formatted license URL: %ls", m_sczLicenseUrl);
3478
3479 hr = UriProtocol(sczLicenseUrl, &protocol);
3480 if (FAILED(hr) || URI_PROTOCOL_UNKNOWN == protocol)
3481 {
3482 // Probe for localized license file
3483 hr = PathRelativeToModule(&sczLicensePath, sczLicenseUrl, m_hModule);
3484 if (SUCCEEDED(hr))
3485 {
3486 hr = PathGetDirectory(sczLicensePath, &sczLicenseDirectory);
3487 if (SUCCEEDED(hr))
3488 {
3489 hr = LocProbeForFile(sczLicenseDirectory, PathFile(sczLicenseUrl), m_sczLanguage, &sczLicensePath);
3490 }
3491 }
3492 }
3493
3494 hr = ShelExecUnelevated(sczLicensePath ? sczLicensePath : sczLicenseUrl, NULL, L"open", NULL, SW_SHOWDEFAULT);
3495 BalExitOnFailure(hr, "Failed to launch URL to EULA.");
3496
3497 LExit:
3498 ReleaseStr(sczLicensePath);
3499 ReleaseStr(sczLicenseUrl);
3500 ReleaseStr(sczLicenseDirectory);
3501 ReleaseStr(sczLicenseFilename);
3502
3503 return;
3504 }
3505
3506
3507 //
3508 // OnClickLaunchButton - launch the app from the success page.
3509 //
3510 void OnClickLaunchButton()
3511 {
3512 HRESULT hr = S_OK;
3513 LPWSTR sczUnformattedLaunchTarget = NULL;
3514 LPWSTR sczLaunchTarget = NULL;
3515 LPWSTR sczLaunchTargetElevatedId = NULL;
3516 LPWSTR sczUnformattedArguments = NULL;
3517 LPWSTR sczArguments = NULL;
3518 LPWSTR sczUnformattedLaunchFolder = NULL;
3519 LPWSTR sczLaunchFolder = NULL;
3520 int nCmdShow = SW_SHOWNORMAL;
3521
3522 hr = BalGetStringVariable(WIXSTDBA_VARIABLE_LAUNCH_TARGET_PATH, &sczUnformattedLaunchTarget);
3523 BalExitOnFailure(hr, "Failed to get launch target variable '%ls'.", WIXSTDBA_VARIABLE_LAUNCH_TARGET_PATH);
3524
3525 hr = BalFormatString(sczUnformattedLaunchTarget, &sczLaunchTarget);
3526 BalExitOnFailure(hr, "Failed to format launch target variable: %ls", sczUnformattedLaunchTarget);
3527
3528 if (BalVariableExists(WIXSTDBA_VARIABLE_LAUNCH_TARGET_ELEVATED_ID))
3529 {
3530 hr = BalGetStringVariable(WIXSTDBA_VARIABLE_LAUNCH_TARGET_ELEVATED_ID, &sczLaunchTargetElevatedId);
3531 BalExitOnFailure(hr, "Failed to get launch target elevated id '%ls'.", WIXSTDBA_VARIABLE_LAUNCH_TARGET_ELEVATED_ID);
3532 }
3533
3534 if (BalVariableExists(WIXSTDBA_VARIABLE_LAUNCH_ARGUMENTS))
3535 {
3536 hr = BalGetStringVariable(WIXSTDBA_VARIABLE_LAUNCH_ARGUMENTS, &sczUnformattedArguments);
3537 BalExitOnFailure(hr, "Failed to get launch arguments '%ls'.", WIXSTDBA_VARIABLE_LAUNCH_ARGUMENTS);
3538 }
3539
3540 if (BalVariableExists(WIXSTDBA_VARIABLE_LAUNCH_HIDDEN))
3541 {
3542 nCmdShow = SW_HIDE;
3543 }
3544
3545 if (BalVariableExists(WIXSTDBA_VARIABLE_LAUNCH_WORK_FOLDER))
3546 {
3547 hr = BalGetStringVariable(WIXSTDBA_VARIABLE_LAUNCH_WORK_FOLDER, &sczUnformattedLaunchFolder);
3548 BalExitOnFailure(hr, "Failed to get launch working directory variable '%ls'.", WIXSTDBA_VARIABLE_LAUNCH_WORK_FOLDER);
3549 }
3550
3551 if (sczLaunchTargetElevatedId && !m_fTriedToLaunchElevated)
3552 {
3553 m_fTriedToLaunchElevated = TRUE;
3554 hr = m_pEngine->LaunchApprovedExe(m_hWnd, sczLaunchTargetElevatedId, sczUnformattedArguments, 0);
3555 if (FAILED(hr))
3556 {
3557 BalLogError(hr, "Failed to launch elevated target: %ls", sczLaunchTargetElevatedId);
3558
3559 //try with ShelExec next time
3560 OnClickLaunchButton();
3561 }
3562 }
3563 else
3564 {
3565 if (sczUnformattedArguments)
3566 {
3567 hr = BalFormatString(sczUnformattedArguments, &sczArguments);
3568 BalExitOnFailure(hr, "Failed to format launch arguments variable: %ls", sczUnformattedArguments);
3569 }
3570
3571 if (sczUnformattedLaunchFolder)
3572 {
3573 hr = BalFormatString(sczUnformattedLaunchFolder, &sczLaunchFolder);
3574 BalExitOnFailure(hr, "Failed to format launch working directory variable: %ls", sczUnformattedLaunchFolder);
3575 }
3576
3577 hr = ShelExec(sczLaunchTarget, sczArguments, L"open", sczLaunchFolder, nCmdShow, m_hWnd, NULL);
3578 BalExitOnFailure(hr, "Failed to launch target: %ls", sczLaunchTarget);
3579
3580 ::PostMessageW(m_hWnd, WM_CLOSE, 0, 0);
3581 }
3582
3583 LExit:
3584 StrSecureZeroFreeString(sczLaunchFolder);
3585 ReleaseStr(sczUnformattedLaunchFolder);
3586 StrSecureZeroFreeString(sczArguments);
3587 ReleaseStr(sczUnformattedArguments);
3588 ReleaseStr(sczLaunchTargetElevatedId);
3589 StrSecureZeroFreeString(sczLaunchTarget);
3590 ReleaseStr(sczUnformattedLaunchTarget);
3591
3592 return;
3593 }
3594
3595
3596 //
3597 // OnClickRestartButton - allows the restart and closes the app.
3598 //
3599 void OnClickRestartButton()
3600 {
3601 AssertSz(m_fRestartRequired, "Restart must be requested to be able to click on the restart button.");
3602
3603 m_fAllowRestart = TRUE;
3604 ::SendMessageW(m_hWnd, WM_CLOSE, 0, 0);
3605
3606 return;
3607 }
3608
3609
3610 //
3611 // OnClickLogFileLink - show the log file.
3612 //
3613 void OnClickLogFileLink()
3614 {
3615 HRESULT hr = S_OK;
3616 LPWSTR sczLogFile = NULL;
3617
3618 hr = BalGetStringVariable(m_Bundle.sczLogVariable, &sczLogFile);
3619 BalExitOnFailure(hr, "Failed to get log file variable '%ls'.", m_Bundle.sczLogVariable);
3620
3621 hr = ShelExecUnelevated(L"notepad.exe", sczLogFile, L"open", NULL, SW_SHOWDEFAULT);
3622 BalExitOnFailure(hr, "Failed to open log file target: %ls", sczLogFile);
3623
3624 LExit:
3625 ReleaseStr(sczLogFile);
3626
3627 return;
3628 }
3629
3630
3631 //
3632 // SetState
3633 //
3634 void SetState(
3635 __in WIXSTDBA_STATE state,
3636 __in HRESULT hrStatus
3637 )
3638 {
3639 if (FAILED(hrStatus))
3640 {
3641 m_hrFinal = hrStatus;
3642 }
3643
3644 if (FAILED(m_hrFinal))
3645 {
3646 state = WIXSTDBA_STATE_FAILED;
3647 }
3648
3649 if (m_state < state)
3650 {
3651 ::PostMessageW(m_hWnd, WM_WIXSTDBA_CHANGE_STATE, 0, state);
3652 }
3653 }
3654
3655
3656 void DeterminePageId(
3657 __in WIXSTDBA_STATE state,
3658 __out DWORD* pdwPageId
3659 )
3660 {
3661 if (BOOTSTRAPPER_DISPLAY_PASSIVE == m_command.display)
3662 {
3663 switch (state)
3664 {
3665 case WIXSTDBA_STATE_INITIALIZED:
3666 *pdwPageId = BOOTSTRAPPER_ACTION_HELP == m_command.action ? m_rgdwPageIds[WIXSTDBA_PAGE_HELP] : m_rgdwPageIds[WIXSTDBA_PAGE_LOADING];
3667 break;
3668
3669 case WIXSTDBA_STATE_HELP:
3670 *pdwPageId = m_rgdwPageIds[WIXSTDBA_PAGE_HELP];
3671 break;
3672
3673 case WIXSTDBA_STATE_DETECTING:
3674 *pdwPageId = m_rgdwPageIds[WIXSTDBA_PAGE_LOADING] ? m_rgdwPageIds[WIXSTDBA_PAGE_LOADING] : m_rgdwPageIds[WIXSTDBA_PAGE_PROGRESS_PASSIVE] ? m_rgdwPageIds[WIXSTDBA_PAGE_PROGRESS_PASSIVE] : m_rgdwPageIds[WIXSTDBA_PAGE_PROGRESS];
3675 break;
3676
3677 case WIXSTDBA_STATE_DETECTED: __fallthrough;
3678 case WIXSTDBA_STATE_PLANNING: __fallthrough;
3679 case WIXSTDBA_STATE_PLANNED: __fallthrough;
3680 case WIXSTDBA_STATE_APPLYING: __fallthrough;
3681 case WIXSTDBA_STATE_CACHING: __fallthrough;
3682 case WIXSTDBA_STATE_CACHED: __fallthrough;
3683 case WIXSTDBA_STATE_EXECUTING: __fallthrough;
3684 case WIXSTDBA_STATE_EXECUTED:
3685 *pdwPageId = m_rgdwPageIds[WIXSTDBA_PAGE_PROGRESS_PASSIVE] ? m_rgdwPageIds[WIXSTDBA_PAGE_PROGRESS_PASSIVE] : m_rgdwPageIds[WIXSTDBA_PAGE_PROGRESS];
3686 break;
3687
3688 default:
3689 *pdwPageId = 0;
3690 break;
3691 }
3692 }
3693 else if (BOOTSTRAPPER_DISPLAY_FULL == m_command.display)
3694 {
3695 switch (state)
3696 {
3697 case WIXSTDBA_STATE_INITIALIZING:
3698 *pdwPageId = 0;
3699 break;
3700
3701 case WIXSTDBA_STATE_INITIALIZED:
3702 *pdwPageId = BOOTSTRAPPER_ACTION_HELP == m_command.action ? m_rgdwPageIds[WIXSTDBA_PAGE_HELP] : m_rgdwPageIds[WIXSTDBA_PAGE_LOADING];
3703 break;
3704
3705 case WIXSTDBA_STATE_HELP:
3706 *pdwPageId = m_rgdwPageIds[WIXSTDBA_PAGE_HELP];
3707 break;
3708
3709 case WIXSTDBA_STATE_DETECTING:
3710 *pdwPageId = m_rgdwPageIds[WIXSTDBA_PAGE_LOADING];
3711 break;
3712
3713 case WIXSTDBA_STATE_DETECTED:
3714 switch (m_command.action)
3715 {
3716 case BOOTSTRAPPER_ACTION_INSTALL:
3717 *pdwPageId = m_rgdwPageIds[WIXSTDBA_PAGE_INSTALL];
3718 break;
3719
3720 case BOOTSTRAPPER_ACTION_MODIFY: __fallthrough;
3721 case BOOTSTRAPPER_ACTION_REPAIR: __fallthrough;
3722 case BOOTSTRAPPER_ACTION_UNINSTALL:
3723 *pdwPageId = m_rgdwPageIds[WIXSTDBA_PAGE_MODIFY];
3724 break;
3725 }
3726 break;
3727
3728 case WIXSTDBA_STATE_PLANNING: __fallthrough;
3729 case WIXSTDBA_STATE_PLANNED: __fallthrough;
3730 case WIXSTDBA_STATE_APPLYING: __fallthrough;
3731 case WIXSTDBA_STATE_CACHING: __fallthrough;
3732 case WIXSTDBA_STATE_CACHED: __fallthrough;
3733 case WIXSTDBA_STATE_EXECUTING: __fallthrough;
3734 case WIXSTDBA_STATE_EXECUTED:
3735 *pdwPageId = m_rgdwPageIds[WIXSTDBA_PAGE_PROGRESS];
3736 break;
3737
3738 case WIXSTDBA_STATE_APPLIED:
3739 *pdwPageId = m_rgdwPageIds[WIXSTDBA_PAGE_SUCCESS];
3740 break;
3741
3742 case WIXSTDBA_STATE_FAILED:
3743 *pdwPageId = m_rgdwPageIds[WIXSTDBA_PAGE_FAILURE];
3744 break;
3745 }
3746 }
3747 }
3748
3749
3750 HRESULT EvaluateConditions()
3751 {
3752 HRESULT hr = S_OK;
3753 BOOL fResult = FALSE;
3754
3755 for (DWORD i = 0; i < m_Conditions.cConditions; ++i)
3756 {
3757 BAL_CONDITION* pCondition = m_Conditions.rgConditions + i;
3758
3759 hr = BalConditionEvaluate(pCondition, m_pEngine, &fResult, &m_sczFailedMessage);
3760 BalExitOnFailure(hr, "Failed to evaluate condition.");
3761
3762 if (!fResult)
3763 {
3764 hr = E_WIXSTDBA_CONDITION_FAILED;
3765 BalExitOnFailure(hr, "%ls", m_sczFailedMessage);
3766 }
3767 }
3768
3769 ReleaseNullStrSecure(m_sczFailedMessage);
3770
3771 LExit:
3772 return hr;
3773 }
3774
3775 void UpdateCacheProgress(
3776 __in DWORD dwOverallPercentage
3777 )
3778 {
3779 WCHAR wzProgress[5] = { };
3780
3781 ::StringCchPrintfW(wzProgress, countof(wzProgress), L"%u%%", dwOverallPercentage);
3782 ThemeSetTextControl(m_pTheme, WIXSTDBA_CONTROL_CACHE_PROGRESS_TEXT, wzProgress);
3783
3784 ThemeSetProgressControl(m_pTheme, WIXSTDBA_CONTROL_CACHE_PROGRESS_BAR, dwOverallPercentage);
3785
3786 m_dwCalculatedCacheProgress = dwOverallPercentage * WIXSTDBA_ACQUIRE_PERCENTAGE / 100;
3787 ThemeSetProgressControl(m_pTheme, WIXSTDBA_CONTROL_OVERALL_CALCULATED_PROGRESS_BAR, m_dwCalculatedCacheProgress + m_dwCalculatedExecuteProgress);
3788
3789 SetTaskbarButtonProgress(m_dwCalculatedCacheProgress + m_dwCalculatedExecuteProgress);
3790 }
3791
3792
3793 void SetTaskbarButtonProgress(
3794 __in DWORD dwOverallPercentage
3795 )
3796 {
3797 HRESULT hr = S_OK;
3798
3799 if (m_fTaskbarButtonOK)
3800 {
3801 hr = m_pTaskbarList->SetProgressValue(m_hWnd, dwOverallPercentage, 100UL);
3802 BalExitOnFailure(hr, "Failed to set taskbar button progress to: %d%%.", dwOverallPercentage);
3803 }
3804
3805 LExit:
3806 return;
3807 }
3808
3809
3810 void SetTaskbarButtonState(
3811 __in TBPFLAG tbpFlags
3812 )
3813 {
3814 HRESULT hr = S_OK;
3815
3816 if (m_fTaskbarButtonOK)
3817 {
3818 hr = m_pTaskbarList->SetProgressState(m_hWnd, tbpFlags);
3819 BalExitOnFailure(hr, "Failed to set taskbar button state.", tbpFlags);
3820 }
3821
3822 LExit:
3823 return;
3824 }
3825
3826
3827 void SetProgressState(
3828 __in HRESULT hrStatus
3829 )
3830 {
3831 TBPFLAG flag = TBPF_NORMAL;
3832
3833 if (IsCanceled() || HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT) == hrStatus)
3834 {
3835 flag = TBPF_PAUSED;
3836 }
3837 else if (IsRollingBack() || FAILED(hrStatus))
3838 {
3839 flag = TBPF_ERROR;
3840 }
3841
3842 SetTaskbarButtonState(flag);
3843 }
3844
3845
3846 HRESULT LoadBAFunctions(
3847 __in IXMLDOMDocument* pixdManifest
3848 )
3849 {
3850 HRESULT hr = S_OK;
3851 IXMLDOMNode* pBAFunctionsNode = NULL;
3852 IXMLDOMNode* pPayloadNode = NULL;
3853 LPWSTR sczPayloadId = NULL;
3854 LPWSTR sczPayloadXPath = NULL;
3855 LPWSTR sczBafName = NULL;
3856 LPWSTR sczBafPath = NULL;
3857 BA_FUNCTIONS_CREATE_ARGS bafCreateArgs = { };
3858 BA_FUNCTIONS_CREATE_RESULTS bafCreateResults = { };
3859
3860 hr = XmlSelectSingleNode(pixdManifest, L"/BootstrapperApplicationData/WixBalBAFunctions", &pBAFunctionsNode);
3861 BalExitOnFailure(hr, "Failed to read WixBalBAFunctions node from BootstrapperApplicationData.xml.");
3862
3863 if (S_FALSE == hr)
3864 {
3865 ExitFunction();
3866 }
3867
3868 hr = XmlGetAttributeEx(pBAFunctionsNode, L"PayloadId", &sczPayloadId);
3869 BalExitOnFailure(hr, "Failed to get BAFunctions PayloadId.");
3870
3871 hr = StrAllocFormatted(&sczPayloadXPath, L"/BootstrapperApplicationData/WixPayloadProperties[@Payload='%ls']", sczPayloadId);
3872 BalExitOnFailure(hr, "Failed to format BAFunctions payload XPath.");
3873
3874 hr = XmlSelectSingleNode(pixdManifest, sczPayloadXPath, &pPayloadNode);
3875 if (S_FALSE == hr)
3876 {
3877 hr = E_NOTFOUND;
3878 }
3879 BalExitOnFailure(hr, "Failed to find WixPayloadProperties node for BAFunctions PayloadId: %ls.", sczPayloadId);
3880
3881 hr = XmlGetAttributeEx(pPayloadNode, L"Name", &sczBafName);
3882 BalExitOnFailure(hr, "Failed to get BAFunctions Name.");
3883
3884 hr = PathRelativeToModule(&sczBafPath, sczBafName, m_hModule);
3885 BalExitOnFailure(hr, "Failed to get path to BAFunctions DLL.");
3886
3887 BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "WIXSTDBA: LoadBAFunctions() - BAFunctions DLL %ls", sczBafPath);
3888
3889 m_hBAFModule = ::LoadLibraryExW(sczBafPath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
3890 BalExitOnNullWithLastError(m_hBAFModule, hr, "WIXSTDBA: LoadBAFunctions() - Failed to load DLL %ls", sczBafPath);
3891
3892 PFN_BA_FUNCTIONS_CREATE pfnBAFunctionsCreate = reinterpret_cast<PFN_BA_FUNCTIONS_CREATE>(::GetProcAddress(m_hBAFModule, "BAFunctionsCreate"));
3893 BalExitOnNullWithLastError(pfnBAFunctionsCreate, hr, "Failed to get BAFunctionsCreate entry-point from: %ls", sczBafPath);
3894
3895 bafCreateArgs.cbSize = sizeof(bafCreateArgs);
3896 bafCreateArgs.qwBAFunctionsAPIVersion = MAKEQWORDVERSION(0, 0, 0, 2); // TODO: need to decide whether to keep this, and if so when to update it.
3897 bafCreateArgs.pBootstrapperCreateArgs = &m_createArgs;
3898
3899 bafCreateResults.cbSize = sizeof(bafCreateResults);
3900
3901 hr = pfnBAFunctionsCreate(&bafCreateArgs, &bafCreateResults);
3902 BalExitOnFailure(hr, "Failed to create BAFunctions.");
3903
3904 m_pfnBAFunctionsProc = bafCreateResults.pfnBAFunctionsProc;
3905 m_pvBAFunctionsProcContext = bafCreateResults.pvBAFunctionsProcContext;
3906
3907 LExit:
3908 if (m_hBAFModule && !m_pfnBAFunctionsProc)
3909 {
3910 ::FreeLibrary(m_hBAFModule);
3911 m_hBAFModule = NULL;
3912 }
3913 ReleaseStr(sczBafPath);
3914 ReleaseStr(sczBafName);
3915 ReleaseStr(sczPayloadXPath);
3916 ReleaseStr(sczPayloadId);
3917 ReleaseObject(pBAFunctionsNode);
3918 ReleaseObject(pPayloadNode);
3919
3920 return hr;
3921 }
3922
3923
3924public:
3925 //
3926 // Constructor - initialize member variables.
3927 //
3928 CWixStandardBootstrapperApplication(
3929 __in HMODULE hModule,
3930 __in BOOL fPrereq,
3931 __in HRESULT hrHostInitialization,
3932 __in IBootstrapperEngine* pEngine,
3933 __in const BOOTSTRAPPER_CREATE_ARGS* pArgs
3934 ) : CBalBaseBootstrapperApplication(pEngine, pArgs, 3, 3000)
3935 {
3936 m_hModule = hModule;
3937 memcpy_s(&m_command, sizeof(m_command), pArgs->pCommand, sizeof(BOOTSTRAPPER_COMMAND));
3938 memcpy_s(&m_createArgs, sizeof(m_createArgs), pArgs, sizeof(BOOTSTRAPPER_CREATE_ARGS));
3939 m_createArgs.pCommand = &m_command;
3940
3941 if (fPrereq)
3942 {
3943 // Pre-req BA should only show help or do an install (to launch the Managed BA which can then do the right action).
3944 if (BOOTSTRAPPER_ACTION_HELP != m_command.action)
3945 {
3946 m_command.action = BOOTSTRAPPER_ACTION_INSTALL;
3947 }
3948 }
3949 else // maybe modify the action state if the bundle is or is not already installed.
3950 {
3951 LONGLONG llInstalled = 0;
3952 HRESULT hr = BalGetNumericVariable(L"WixBundleInstalled", &llInstalled);
3953 if (SUCCEEDED(hr) && BOOTSTRAPPER_RESUME_TYPE_REBOOT != m_command.resumeType && 0 < llInstalled && BOOTSTRAPPER_ACTION_INSTALL == m_command.action)
3954 {
3955 m_command.action = BOOTSTRAPPER_ACTION_MODIFY;
3956 }
3957 else if (0 == llInstalled && (BOOTSTRAPPER_ACTION_MODIFY == m_command.action || BOOTSTRAPPER_ACTION_REPAIR == m_command.action))
3958 {
3959 m_command.action = BOOTSTRAPPER_ACTION_INSTALL;
3960 }
3961 }
3962
3963 m_plannedAction = BOOTSTRAPPER_ACTION_UNKNOWN;
3964
3965 // When resuming from restart doing some install-like operation, try to find the package that forced the
3966 // restart. We'll use this information during planning.
3967 m_sczAfterForcedRestartPackage = NULL;
3968
3969 if (BOOTSTRAPPER_RESUME_TYPE_REBOOT == m_command.resumeType && BOOTSTRAPPER_ACTION_UNINSTALL < m_command.action)
3970 {
3971 // Ensure the forced restart package variable is null when it is an empty string.
3972 HRESULT hr = BalGetStringVariable(L"WixBundleForcedRestartPackage", &m_sczAfterForcedRestartPackage);
3973 if (FAILED(hr) || !m_sczAfterForcedRestartPackage || !*m_sczAfterForcedRestartPackage)
3974 {
3975 ReleaseNullStr(m_sczAfterForcedRestartPackage);
3976 }
3977 }
3978
3979 m_pWixLoc = NULL;
3980 memset(&m_Bundle, 0, sizeof(m_Bundle));
3981 memset(&m_Conditions, 0, sizeof(m_Conditions));
3982 m_sczConfirmCloseMessage = NULL;
3983 m_sczFailedMessage = NULL;
3984
3985 m_sczLanguage = NULL;
3986 m_pTheme = NULL;
3987 memset(m_rgdwPageIds, 0, sizeof(m_rgdwPageIds));
3988 m_hUiThread = NULL;
3989 m_fRegistered = FALSE;
3990 m_hWnd = NULL;
3991
3992 m_state = WIXSTDBA_STATE_INITIALIZING;
3993 m_hrFinal = hrHostInitialization;
3994
3995 m_fDowngrading = FALSE;
3996 m_restartResult = BOOTSTRAPPER_APPLY_RESTART_NONE;
3997 m_fRestartRequired = FALSE;
3998 m_fAllowRestart = FALSE;
3999
4000 m_sczLicenseFile = NULL;
4001 m_sczLicenseUrl = NULL;
4002 m_fSuppressDowngradeFailure = FALSE;
4003 m_fSuppressRepair = FALSE;
4004 m_fSupportCacheOnly = FALSE;
4005
4006 m_sdOverridableVariables = NULL;
4007 m_pTaskbarList = NULL;
4008 m_uTaskbarButtonCreatedMessage = UINT_MAX;
4009 m_fTaskbarButtonOK = FALSE;
4010 ::InitializeCriticalSection(&m_csShowingInternalUiThisPackage);
4011 m_fShowingInternalUiThisPackage = FALSE;
4012 m_fTriedToLaunchElevated = FALSE;
4013
4014 m_fPrereq = fPrereq;
4015 m_fPrereqInstalled = FALSE;
4016 m_fPrereqAlreadyInstalled = FALSE;
4017
4018 pEngine->AddRef();
4019 m_pEngine = pEngine;
4020
4021 m_hBAFModule = NULL;
4022 m_pfnBAFunctionsProc = NULL;
4023 m_pvBAFunctionsProcContext = NULL;
4024 }
4025
4026
4027 //
4028 // Destructor - release member variables.
4029 //
4030 ~CWixStandardBootstrapperApplication()
4031 {
4032 AssertSz(!::IsWindow(m_hWnd), "Window should have been destroyed before destructor.");
4033 AssertSz(!m_pTaskbarList, "Taskbar should have been released before destructor.");
4034 AssertSz(!m_pTheme, "Theme should have been released before destructor.");
4035
4036 for (DWORD i = 0; i < m_Bundle.packages.cPackages; ++i)
4037 {
4038 ReleaseMem(m_Bundle.packages.rgPackages[i].pvCustomData);
4039 }
4040
4041 ::DeleteCriticalSection(&m_csShowingInternalUiThisPackage);
4042 ReleaseDict(m_sdOverridableVariables);
4043 ReleaseStr(m_sczFailedMessage);
4044 ReleaseStr(m_sczConfirmCloseMessage);
4045 BalConditionsUninitialize(&m_Conditions);
4046 BalInfoUninitialize(&m_Bundle);
4047 LocFree(m_pWixLoc);
4048
4049 ReleaseStr(m_sczLanguage);
4050 ReleaseStr(m_sczLicenseFile);
4051 ReleaseStr(m_sczLicenseUrl);
4052 ReleaseStr(m_sczAfterForcedRestartPackage);
4053 ReleaseNullObject(m_pEngine);
4054
4055 if (m_hBAFModule)
4056 {
4057 PFN_BA_FUNCTIONS_DESTROY pfnBAFunctionsDestroy = reinterpret_cast<PFN_BA_FUNCTIONS_DESTROY>(::GetProcAddress(m_hBAFModule, "BAFunctionsDestroy"));
4058 if (pfnBAFunctionsDestroy)
4059 {
4060 pfnBAFunctionsDestroy();
4061 }
4062
4063 ::FreeLibrary(m_hBAFModule);
4064 m_hBAFModule = NULL;
4065 }
4066 }
4067
4068private:
4069 HMODULE m_hModule;
4070 BOOTSTRAPPER_CREATE_ARGS m_createArgs;
4071 BOOTSTRAPPER_COMMAND m_command;
4072 IBootstrapperEngine* m_pEngine;
4073 BOOTSTRAPPER_ACTION m_plannedAction;
4074
4075 LPWSTR m_sczAfterForcedRestartPackage;
4076
4077 WIX_LOCALIZATION* m_pWixLoc;
4078 BAL_INFO_BUNDLE m_Bundle;
4079 BAL_CONDITIONS m_Conditions;
4080 LPWSTR m_sczFailedMessage;
4081 LPWSTR m_sczConfirmCloseMessage;
4082
4083 LPWSTR m_sczLanguage;
4084 THEME* m_pTheme;
4085 DWORD m_rgdwPageIds[countof(vrgwzPageNames)];
4086 HANDLE m_hUiThread;
4087 BOOL m_fRegistered;
4088 HWND m_hWnd;
4089
4090 WIXSTDBA_STATE m_state;
4091 HRESULT m_hrFinal;
4092
4093 BOOL m_fStartedExecution;
4094 DWORD m_dwCalculatedCacheProgress;
4095 DWORD m_dwCalculatedExecuteProgress;
4096
4097 BOOL m_fDowngrading;
4098 BOOTSTRAPPER_APPLY_RESTART m_restartResult;
4099 BOOL m_fRestartRequired;
4100 BOOL m_fAllowRestart;
4101
4102 LPWSTR m_sczLicenseFile;
4103 LPWSTR m_sczLicenseUrl;
4104 BOOL m_fSuppressDowngradeFailure;
4105 BOOL m_fSuppressRepair;
4106 BOOL m_fSupportCacheOnly;
4107
4108 STRINGDICT_HANDLE m_sdOverridableVariables;
4109
4110 BOOL m_fPrereq;
4111 BOOL m_fPrereqInstalled;
4112 BOOL m_fPrereqAlreadyInstalled;
4113
4114 ITaskbarList3* m_pTaskbarList;
4115 UINT m_uTaskbarButtonCreatedMessage;
4116 BOOL m_fTaskbarButtonOK;
4117 CRITICAL_SECTION m_csShowingInternalUiThisPackage;
4118 BOOL m_fShowingInternalUiThisPackage;
4119 BOOL m_fTriedToLaunchElevated;
4120
4121 HMODULE m_hBAFModule;
4122 PFN_BA_FUNCTIONS_PROC m_pfnBAFunctionsProc;
4123 LPVOID m_pvBAFunctionsProcContext;
4124};
4125
4126
4127//
4128// CreateBootstrapperApplication - creates a new IBootstrapperApplication object.
4129//
4130HRESULT CreateBootstrapperApplication(
4131 __in HMODULE hModule,
4132 __in BOOL fPrereq,
4133 __in HRESULT hrHostInitialization,
4134 __in IBootstrapperEngine* pEngine,
4135 __in const BOOTSTRAPPER_CREATE_ARGS* pArgs,
4136 __inout BOOTSTRAPPER_CREATE_RESULTS* pResults,
4137 __out IBootstrapperApplication** ppApplication
4138 )
4139{
4140 HRESULT hr = S_OK;
4141 CWixStandardBootstrapperApplication* pApplication = NULL;
4142
4143 if (BOOTSTRAPPER_DISPLAY_UNKNOWN == pArgs->pCommand->display)
4144 {
4145 BalExitOnFailure(hr = E_INVALIDARG, "Engine requested Unknown display type.");
4146 }
4147
4148 pApplication = new CWixStandardBootstrapperApplication(hModule, fPrereq, hrHostInitialization, pEngine, pArgs);
4149 ExitOnNull(pApplication, hr, E_OUTOFMEMORY, "Failed to create new standard bootstrapper application object.");
4150
4151 pResults->pfnBootstrapperApplicationProc = BalBaseBootstrapperApplicationProc;
4152 pResults->pvBootstrapperApplicationProcContext = pApplication;
4153 *ppApplication = pApplication;
4154 pApplication = NULL;
4155
4156LExit:
4157 ReleaseObject(pApplication);
4158 return hr;
4159}
4160
4161
4162static HRESULT DAPI EvaluateVariableConditionCallback(
4163 __in_z LPCWSTR wzCondition,
4164 __out BOOL* pf,
4165 __in_opt LPVOID /*pvContext*/
4166 )
4167{
4168 return BalEvaluateCondition(wzCondition, pf);
4169}
4170
4171
4172static HRESULT DAPI FormatVariableStringCallback(
4173 __in_z LPCWSTR wzFormat,
4174 __inout LPWSTR* psczOut,
4175 __in_opt LPVOID /*pvContext*/
4176 )
4177{
4178 return BalFormatString(wzFormat, psczOut);
4179}
4180
4181
4182static HRESULT DAPI GetVariableNumericCallback(
4183 __in_z LPCWSTR wzVariable,
4184 __out LONGLONG* pllValue,
4185 __in_opt LPVOID /*pvContext*/
4186 )
4187{
4188 return BalGetNumericVariable(wzVariable, pllValue);
4189}
4190
4191
4192static HRESULT DAPI SetVariableNumericCallback(
4193 __in_z LPCWSTR wzVariable,
4194 __in LONGLONG llValue,
4195 __in_opt LPVOID /*pvContext*/
4196 )
4197{
4198 return BalSetNumericVariable(wzVariable, llValue);
4199}
4200
4201
4202static HRESULT DAPI GetVariableStringCallback(
4203 __in_z LPCWSTR wzVariable,
4204 __inout LPWSTR* psczValue,
4205 __in_opt LPVOID /*pvContext*/
4206 )
4207{
4208 return BalGetStringVariable(wzVariable, psczValue);
4209}
4210
4211
4212static HRESULT DAPI SetVariableStringCallback(
4213 __in_z LPCWSTR wzVariable,
4214 __in_z_opt LPCWSTR wzValue,
4215 __in BOOL fFormatted,
4216 __in_opt LPVOID /*pvContext*/
4217 )
4218{
4219 return BalSetStringVariable(wzVariable, wzValue, fFormatted);
4220}
4221
4222static LPCSTR LoggingRequestStateToString(
4223 __in BOOTSTRAPPER_REQUEST_STATE requestState
4224 )
4225{
4226 switch (requestState)
4227 {
4228 case BOOTSTRAPPER_REQUEST_STATE_NONE:
4229 return "None";
4230 case BOOTSTRAPPER_REQUEST_STATE_FORCE_ABSENT:
4231 return "ForceAbsent";
4232 case BOOTSTRAPPER_REQUEST_STATE_ABSENT:
4233 return "Absent";
4234 case BOOTSTRAPPER_REQUEST_STATE_CACHE:
4235 return "Cache";
4236 case BOOTSTRAPPER_REQUEST_STATE_PRESENT:
4237 return "Present";
4238 case BOOTSTRAPPER_REQUEST_STATE_REPAIR:
4239 return "Repair";
4240 default:
4241 return "Invalid";
4242 }
4243}
4244
4245static LPCSTR LoggingMsiFeatureStateToString(
4246 __in BOOTSTRAPPER_FEATURE_STATE featureState
4247 )
4248{
4249 switch (featureState)
4250 {
4251 case BOOTSTRAPPER_FEATURE_STATE_UNKNOWN:
4252 return "Unknown";
4253 case BOOTSTRAPPER_FEATURE_STATE_ABSENT:
4254 return "Absent";
4255 case BOOTSTRAPPER_FEATURE_STATE_ADVERTISED:
4256 return "Advertised";
4257 case BOOTSTRAPPER_FEATURE_STATE_LOCAL:
4258 return "Local";
4259 case BOOTSTRAPPER_FEATURE_STATE_SOURCE:
4260 return "Source";
4261 default:
4262 return "Invalid";
4263 }
4264}