summaryrefslogtreecommitdiff
path: root/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp')
-rw-r--r--src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp5372
1 files changed, 0 insertions, 5372 deletions
diff --git a/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp b/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp
deleted file mode 100644
index e4eee002..00000000
--- a/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp
+++ /dev/null
@@ -1,5372 +0,0 @@
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_CANRESTART = L"WixCanRestart";
8static const LPCWSTR WIXBUNDLE_VARIABLE_ELEVATED = L"WixBundleElevated";
9
10static const LPCWSTR WIXSTDBA_WINDOW_CLASS = L"WixStdBA";
11
12static const LPCWSTR WIXSTDBA_VARIABLE_INSTALL_FOLDER = L"InstallFolder";
13static const LPCWSTR WIXSTDBA_VARIABLE_LAUNCH_TARGET_PATH = L"LaunchTarget";
14static const LPCWSTR WIXSTDBA_VARIABLE_LAUNCH_TARGET_ELEVATED_ID = L"LaunchTargetElevatedId";
15static const LPCWSTR WIXSTDBA_VARIABLE_LAUNCH_ARGUMENTS = L"LaunchArguments";
16static const LPCWSTR WIXSTDBA_VARIABLE_LAUNCH_HIDDEN = L"LaunchHidden";
17static const LPCWSTR WIXSTDBA_VARIABLE_LAUNCH_WORK_FOLDER = L"LaunchWorkingFolder";
18
19static const DWORD WIXSTDBA_ACQUIRE_PERCENTAGE = 30;
20
21static const LPCWSTR WIXSTDBA_VARIABLE_BUNDLE_FILE_VERSION = L"WixBundleFileVersion";
22static const LPCWSTR WIXSTDBA_VARIABLE_LANGUAGE_ID = L"WixStdBALanguageId";
23static const LPCWSTR WIXSTDBA_VARIABLE_RESTART_REQUIRED = L"WixStdBARestartRequired";
24static const LPCWSTR WIXSTDBA_VARIABLE_SHOW_VERSION = L"WixStdBAShowVersion";
25static const LPCWSTR WIXSTDBA_VARIABLE_SUPPRESS_OPTIONS_UI = L"WixStdBASuppressOptionsUI";
26static const LPCWSTR WIXSTDBA_VARIABLE_UPDATE_AVAILABLE = L"WixStdBAUpdateAvailable";
27
28enum WIXSTDBA_STATE
29{
30 WIXSTDBA_STATE_INITIALIZING,
31 WIXSTDBA_STATE_INITIALIZED,
32 WIXSTDBA_STATE_HELP,
33 WIXSTDBA_STATE_DETECTING,
34 WIXSTDBA_STATE_DETECTED,
35 WIXSTDBA_STATE_PLANNING_PREREQS,
36 WIXSTDBA_STATE_PLANNED_PREREQS,
37 WIXSTDBA_STATE_PLANNING,
38 WIXSTDBA_STATE_PLANNED,
39 WIXSTDBA_STATE_APPLYING,
40 WIXSTDBA_STATE_CACHING,
41 WIXSTDBA_STATE_CACHED,
42 WIXSTDBA_STATE_EXECUTING,
43 WIXSTDBA_STATE_EXECUTED,
44 WIXSTDBA_STATE_APPLIED,
45 WIXSTDBA_STATE_FAILED,
46};
47
48enum WM_WIXSTDBA
49{
50 WM_WIXSTDBA_SHOW_HELP = WM_APP + 100,
51 WM_WIXSTDBA_DETECT_PACKAGES,
52 WM_WIXSTDBA_PLAN_PACKAGES,
53 WM_WIXSTDBA_APPLY_PACKAGES,
54 WM_WIXSTDBA_CHANGE_STATE,
55 WM_WIXSTDBA_SHOW_FAILURE,
56 WM_WIXSTDBA_PLAN_PREREQS,
57};
58
59// This enum must be kept in the same order as the vrgwzPageNames array.
60enum WIXSTDBA_PAGE
61{
62 WIXSTDBA_PAGE_LOADING,
63 WIXSTDBA_PAGE_HELP,
64 WIXSTDBA_PAGE_INSTALL,
65 WIXSTDBA_PAGE_MODIFY,
66 WIXSTDBA_PAGE_PROGRESS,
67 WIXSTDBA_PAGE_PROGRESS_PASSIVE,
68 WIXSTDBA_PAGE_SUCCESS,
69 WIXSTDBA_PAGE_FAILURE,
70 COUNT_WIXSTDBA_PAGE,
71};
72
73// This array must be kept in the same order as the WIXSTDBA_PAGE enum.
74static LPCWSTR vrgwzPageNames[] = {
75 L"Loading",
76 L"Help",
77 L"Install",
78 L"Modify",
79 L"Progress",
80 L"ProgressPassive",
81 L"Success",
82 L"Failure",
83};
84
85// The range [0, 100) is unused to avoid collisions with system ids,
86// the range [100, 0x4000) is unused to avoid collisions with thmutil,
87// the range [0x4000, 0x8000) is unused to avoid collisions with BAFunctions.
88const WORD WIXSTDBA_FIRST_ASSIGN_CONTROL_ID = 0x8000;
89
90enum WIXSTDBA_CONTROL
91{
92 // Welcome page
93 WIXSTDBA_CONTROL_INSTALL_BUTTON = WIXSTDBA_FIRST_ASSIGN_CONTROL_ID,
94 WIXSTDBA_CONTROL_EULA_RICHEDIT,
95 WIXSTDBA_CONTROL_EULA_LINK,
96 WIXSTDBA_CONTROL_EULA_ACCEPT_CHECKBOX,
97
98 // Modify page
99 WIXSTDBA_CONTROL_REPAIR_BUTTON,
100 WIXSTDBA_CONTROL_UNINSTALL_BUTTON,
101
102 // Updates
103 WIXSTDBA_CONTROL_CHECKING_FOR_UPDATES_LABEL,
104 WIXSTDBA_CONTROL_INSTALL_UPDATE_BUTTON,
105 WIXSTDBA_CONTROL_MODIFY_UPDATE_BUTTON,
106
107 // Progress page
108 WIXSTDBA_CONTROL_CACHE_PROGRESS_PACKAGE_TEXT,
109 WIXSTDBA_CONTROL_CACHE_PROGRESS_BAR,
110 WIXSTDBA_CONTROL_CACHE_PROGRESS_TEXT,
111
112 WIXSTDBA_CONTROL_EXECUTE_PROGRESS_PACKAGE_TEXT,
113 WIXSTDBA_CONTROL_EXECUTE_PROGRESS_BAR,
114 WIXSTDBA_CONTROL_EXECUTE_PROGRESS_TEXT,
115 WIXSTDBA_CONTROL_EXECUTE_PROGRESS_ACTIONDATA_TEXT,
116
117 WIXSTDBA_CONTROL_OVERALL_PROGRESS_PACKAGE_TEXT,
118 WIXSTDBA_CONTROL_OVERALL_PROGRESS_BAR,
119 WIXSTDBA_CONTROL_OVERALL_CALCULATED_PROGRESS_BAR,
120 WIXSTDBA_CONTROL_OVERALL_PROGRESS_TEXT,
121
122 WIXSTDBA_CONTROL_PROGRESS_CANCEL_BUTTON,
123
124 // Success page
125 WIXSTDBA_CONTROL_LAUNCH_BUTTON,
126 WIXSTDBA_CONTROL_SUCCESS_RESTART_BUTTON,
127
128 // Failure page
129 WIXSTDBA_CONTROL_FAILURE_LOGFILE_LINK,
130 WIXSTDBA_CONTROL_FAILURE_MESSAGE_TEXT,
131 WIXSTDBA_CONTROL_FAILURE_RESTART_BUTTON,
132
133 LAST_WIXSTDBA_CONTROL,
134};
135
136
137static HRESULT DAPI EvaluateVariableConditionCallback(
138 __in_z LPCWSTR wzCondition,
139 __out BOOL* pf,
140 __in_opt LPVOID pvContext
141 );
142static HRESULT DAPI FormatVariableStringCallback(
143 __in_z LPCWSTR wzFormat,
144 __inout LPWSTR* psczOut,
145 __in_opt LPVOID pvContext
146 );
147static HRESULT DAPI GetVariableNumericCallback(
148 __in_z LPCWSTR wzVariable,
149 __out LONGLONG* pllValue,
150 __in_opt LPVOID pvContext
151 );
152static HRESULT DAPI SetVariableNumericCallback(
153 __in_z LPCWSTR wzVariable,
154 __in LONGLONG llValue,
155 __in_opt LPVOID pvContext
156 );
157static HRESULT DAPI GetVariableStringCallback(
158 __in_z LPCWSTR wzVariable,
159 __inout LPWSTR* psczValue,
160 __in_opt LPVOID pvContext
161 );
162static HRESULT DAPI SetVariableStringCallback(
163 __in_z LPCWSTR wzVariable,
164 __in_z_opt LPCWSTR wzValue,
165 __in BOOL fFormatted,
166 __in_opt LPVOID pvContext
167 );
168static LPCSTR LoggingBoolToString(
169 __in BOOL f
170 );
171static LPCSTR LoggingRequestStateToString(
172 __in BOOTSTRAPPER_REQUEST_STATE requestState
173 );
174static LPCSTR LoggingPlanRelationTypeToString(
175 __in BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE type
176 );
177static LPCSTR LoggingMsiFeatureStateToString(
178 __in BOOTSTRAPPER_FEATURE_STATE featureState
179 );
180
181
182class CWixStandardBootstrapperApplication : public CBalBaseBootstrapperApplication
183{
184public: // IBootstrapperApplication
185 virtual STDMETHODIMP OnStartup()
186 {
187 HRESULT hr = S_OK;
188 DWORD dwUIThreadId = 0;
189
190 // create UI thread
191 m_hUiThread = ::CreateThread(NULL, 0, UiThreadProc, this, 0, &dwUIThreadId);
192 if (!m_hUiThread)
193 {
194 BalExitWithLastError(hr, "Failed to create UI thread.");
195 }
196
197 LExit:
198 return hr;
199 }
200
201
202 virtual STDMETHODIMP OnShutdown(
203 __inout BOOTSTRAPPER_SHUTDOWN_ACTION* pAction
204 )
205 {
206 HRESULT hr = S_OK;
207
208 // wait for UI thread to terminate
209 if (m_hUiThread)
210 {
211 ::WaitForSingleObject(m_hUiThread, INFINITE);
212 ReleaseHandle(m_hUiThread);
213 }
214
215 // If a restart was required.
216 if (m_fRestartRequired)
217 {
218 if (m_fShouldRestart && m_fAllowRestart)
219 {
220 *pAction = BOOTSTRAPPER_SHUTDOWN_ACTION_RESTART;
221 }
222
223 if (m_fPrereq)
224 {
225 BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, BOOTSTRAPPER_SHUTDOWN_ACTION_RESTART == *pAction
226 ? "The prerequisites scheduled a restart. The bootstrapper application will be reloaded after the computer is restarted."
227 : "A restart is required by the prerequisites but the user delayed it. The bootstrapper application will be reloaded after the computer is restarted.");
228 }
229 }
230 else if (m_fPrereqInstalled || m_fPrereqSkipped)
231 {
232 BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, m_fPrereqInstalled
233 ? "The prerequisites were successfully installed. The bootstrapper application will be reloaded."
234 : "The prerequisites were already installed. The bootstrapper application will be reloaded.");
235 *pAction = BOOTSTRAPPER_SHUTDOWN_ACTION_RELOAD_BOOTSTRAPPER;
236 m_pPrereqData->fCompleted = TRUE;
237 }
238 else if (m_fPrereq)
239 {
240 BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "The prerequisites were not successfully installed, error: 0x%x. The bootstrapper application will be not reloaded.", m_hrFinal);
241 }
242
243 return hr;
244 }
245
246 virtual STDMETHODIMP OnDetectBegin(
247 __in BOOL fCached,
248 __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType,
249 __in DWORD cPackages,
250 __inout BOOL* pfCancel
251 )
252 {
253 HRESULT hr = S_OK;
254 BOOL fInstalled = BOOTSTRAPPER_REGISTRATION_TYPE_FULL == registrationType;
255
256 if (m_fPrereq)
257 {
258 if (m_pPrereqData->fPerformLayout && BOOTSTRAPPER_ACTION_LAYOUT == m_command.action)
259 {
260 // The parent BA has requested that this BA be in charge of layout.
261 m_fPrereq = FALSE;
262 }
263 else
264 {
265 m_fPreplanPrereqs = m_pPrereqData->fAlwaysInstallPrereqs;
266
267 // Pre-req BA should only show help or do an install (to launch the parent BA which can then do the right action).
268 if (BOOTSTRAPPER_ACTION_HELP != m_command.action)
269 {
270 m_command.action = BOOTSTRAPPER_ACTION_INSTALL;
271 }
272 }
273 }
274 else if (BOOTSTRAPPER_DISPLAY_FULL <= m_command.display) // only modify the action state if showing full UI.
275 {
276 // Maybe modify the action state if the bundle is or is not already installed.
277 if (fInstalled && BOOTSTRAPPER_RESUME_TYPE_REBOOT != m_command.resumeType && BOOTSTRAPPER_ACTION_INSTALL == m_command.action)
278 {
279 m_command.action = BOOTSTRAPPER_ACTION_MODIFY;
280 }
281 else if (!fInstalled && (BOOTSTRAPPER_ACTION_MODIFY == m_command.action || BOOTSTRAPPER_ACTION_REPAIR == m_command.action))
282 {
283 m_command.action = BOOTSTRAPPER_ACTION_INSTALL;
284 }
285 }
286
287 // When resuming from restart doing some install-like operation, try to find the package that forced the
288 // restart. We'll use this information during planning.
289 if (BOOTSTRAPPER_RESUME_TYPE_REBOOT == m_command.resumeType && BOOTSTRAPPER_ACTION_UNINSTALL < m_command.action)
290 {
291 // Ensure the forced restart package variable is null when it is an empty string.
292 hr = BalGetStringVariable(L"WixBundleForcedRestartPackage", &m_sczAfterForcedRestartPackage);
293 if (FAILED(hr) || !m_sczAfterForcedRestartPackage || !*m_sczAfterForcedRestartPackage)
294 {
295 ReleaseNullStr(m_sczAfterForcedRestartPackage);
296 }
297
298 hr = S_OK;
299 }
300
301 if (!m_fPreplanPrereqs)
302 {
303 // If the UI should be visible, display it now and hide the splash screen
304 if (BOOTSTRAPPER_DISPLAY_NONE < m_command.display)
305 {
306 ::ShowWindow(m_pTheme->hwndParent, SW_SHOW);
307 }
308
309 m_pEngine->CloseSplashScreen();
310 }
311
312 return __super::OnDetectBegin(fCached, registrationType, cPackages, pfCancel);
313 }
314
315 virtual STDMETHODIMP OnDetectRelatedBundle(
316 __in LPCWSTR wzBundleId,
317 __in BOOTSTRAPPER_RELATION_TYPE relationType,
318 __in LPCWSTR wzBundleTag,
319 __in BOOL fPerMachine,
320 __in LPCWSTR wzVersion,
321 __in BOOL fMissingFromCache,
322 __inout BOOL* pfCancel
323 )
324 {
325 BAL_INFO_PACKAGE* pPackage = NULL;
326
327 if (!fMissingFromCache)
328 {
329 BalInfoAddRelatedBundleAsPackage(&m_Bundle.packages, wzBundleId, relationType, fPerMachine, &pPackage);
330 // Best effort
331 }
332
333 if (BOOTSTRAPPER_ACTION_INSTALL == m_command.action && BOOTSTRAPPER_RELATION_UPGRADE != m_command.relationType && BOOTSTRAPPER_RELATION_UPGRADE == relationType)
334 {
335 int nResult = 0;
336 HRESULT hr = VerCompareStringVersions(m_sczBundleVersion, wzVersion, TRUE/*fStrict*/, &nResult);
337 BalExitOnFailure(hr, "Failed to compare bundle version: %ls to related bundle version: %ls.", m_sczBundleVersion, wzVersion);
338
339 if (0 > nResult)
340 {
341 m_fDowngrading = TRUE;
342
343 BalLog(BOOTSTRAPPER_LOG_LEVEL_VERBOSE, "Related bundle version: %ls is a downgrade for bundle version: %ls.", wzVersion, m_sczBundleVersion);
344 }
345 }
346
347 LExit:
348 return CBalBaseBootstrapperApplication::OnDetectRelatedBundle(wzBundleId, relationType, wzBundleTag, fPerMachine, wzVersion, fMissingFromCache, pfCancel);
349 }
350
351
352 virtual STDMETHODIMP OnDetectUpdateBegin(
353 __in_z LPCWSTR wzUpdateLocation,
354 __inout BOOL* pfCancel,
355 __inout BOOL* pfSkip
356 )
357 {
358#ifdef DEBUG
359 BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "WIXSTDBA: OnDetectUpdateBegin() - update location: %ls", wzUpdateLocation);
360#endif
361
362 // Try update detection only if we have a potential update source and are in full UI mode.
363 *pfSkip = !wzUpdateLocation
364 || !*wzUpdateLocation
365 || BOOTSTRAPPER_DISPLAY_FULL != m_command.display;
366
367 ThemeShowControl(m_pControlCheckingForUpdatesLabel, *pfSkip ? SW_HIDE : SW_SHOW);
368
369 return __super::OnDetectUpdateBegin(wzUpdateLocation, pfCancel, pfSkip);
370 }
371
372
373 virtual STDMETHODIMP OnDetectUpdate(
374 __in_z LPCWSTR wzUpdateLocation,
375 __in DWORD64 dw64Size,
376 __in_z_opt LPCWSTR wzHash,
377 __in BOOTSTRAPPER_UPDATE_HASH_TYPE hashAlgorithm,
378 __in LPCWSTR wzUpdateVersion,
379 __in_z LPCWSTR wzTitle,
380 __in_z LPCWSTR wzSummary,
381 __in_z LPCWSTR wzContentType,
382 __in_z LPCWSTR wzContent,
383 __inout BOOL* pfCancel,
384 __inout BOOL* pfStopProcessingUpdates
385 )
386 {
387#ifdef DEBUG
388 BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "WIXSTDBA: OnDetectUpdate() - update location: %ls, version: %ls", wzUpdateLocation, wzUpdateVersion);
389#endif
390
391 HRESULT hr = S_OK;
392 int nResult = 0;
393
394 hr = VerCompareStringVersions(m_sczBundleVersion, wzUpdateVersion, TRUE/*fStrict*/, &nResult);
395 BalExitOnFailure(hr, "Failed to compare bundle version: %ls to update version: %ls.", m_sczBundleVersion, wzUpdateVersion);
396
397 // Burn sends the feed in descending version order so we need only the first one.
398 *pfStopProcessingUpdates = TRUE;
399
400 if (0 <= nResult)
401 {
402 BalLog(BOOTSTRAPPER_LOG_LEVEL_VERBOSE, "WIXSTDBA: Update version: %ls is a match or downgrade for bundle version: %ls.", wzUpdateVersion, m_sczBundleVersion);
403 }
404 else
405 {
406 BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "WIXSTDBA: Update v%ls for bundle v%ls available from: %ls.", wzUpdateVersion, m_sczBundleVersion, wzUpdateLocation);
407
408 hr = BalSetVersionVariable(WIXSTDBA_VARIABLE_UPDATE_AVAILABLE, wzUpdateVersion);
409 BalExitOnFailure(hr, "Failed to set WixStdBAUpdateAvailable value: %ls.", wzUpdateVersion);
410
411 hr = m_pEngine->SetUpdate(NULL, wzUpdateLocation, dw64Size, hashAlgorithm, wzHash);
412 BalExitOnFailure(hr, "Failed to set update location: %ls.", wzUpdateLocation);
413 }
414
415 LExit:
416 return __super::OnDetectUpdate(wzUpdateLocation, dw64Size, wzHash, hashAlgorithm, wzUpdateVersion, wzTitle, wzSummary, wzContentType, wzContent, pfCancel, pfStopProcessingUpdates);
417 }
418
419
420 virtual STDMETHODIMP OnDetectUpdateComplete(
421 __in HRESULT /*hrStatus*/,
422 __inout BOOL* pfIgnoreError
423 )
424 {
425 // A failed update is very sad indeed, but shouldn't be fatal.
426 *pfIgnoreError = TRUE;
427
428 return S_OK;
429 }
430
431 virtual STDMETHODIMP OnDetectComplete(
432 __in HRESULT hrStatus,
433 __in BOOL /*fEligibleForCleanup*/
434 )
435 {
436 HRESULT hr = S_OK;
437
438 if (m_fSuppressDowngradeFailure && m_fDowngrading)
439 {
440 SetState(WIXSTDBA_STATE_APPLIED, hrStatus);
441
442 BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Bundle downgrade was attempted but downgrade failure has been suppressed.");
443
444 ExitFunction();
445 }
446
447 // If we're not interacting with the user or we're doing a layout or we're resuming just after a force restart
448 // then automatically start planning.
449 BOOL fSkipToPlan = SUCCEEDED(hrStatus) &&
450 (BOOTSTRAPPER_DISPLAY_FULL > m_command.display ||
451 BOOTSTRAPPER_ACTION_LAYOUT == m_command.action ||
452 BOOTSTRAPPER_RESUME_TYPE_REBOOT == m_command.resumeType);
453
454 // If we're requiring user input (which currently means Install, Repair, or Uninstall)
455 // or if we're skipping to an action that modifies machine state
456 // then evaluate conditions.
457 BOOL fEvaluateConditions = SUCCEEDED(hrStatus) &&
458 (!fSkipToPlan || BOOTSTRAPPER_ACTION_LAYOUT < m_command.action && BOOTSTRAPPER_ACTION_UPDATE_REPLACE > m_command.action);
459
460 if (fEvaluateConditions)
461 {
462 hrStatus = EvaluateConditions();
463 }
464
465 SetState(WIXSTDBA_STATE_DETECTED, hrStatus);
466
467 if (SUCCEEDED(hrStatus))
468 {
469 if (m_fPreplanPrereqs)
470 {
471 ::PostMessageW(m_hWnd, WM_WIXSTDBA_PLAN_PREREQS, 0, BOOTSTRAPPER_ACTION_INSTALL);
472 }
473 else if (fSkipToPlan)
474 {
475 ::PostMessageW(m_hWnd, WM_WIXSTDBA_PLAN_PACKAGES, 0, m_command.action);
476 }
477 }
478
479 LExit:
480 return hr;
481 }
482
483
484 virtual STDMETHODIMP OnPlanBegin(
485 __in DWORD cPackages,
486 __in BOOL* pfCancel
487 )
488 {
489 m_fPrereqPackagePlanned = FALSE;
490
491 return __super::OnPlanBegin(cPackages, pfCancel);
492 }
493
494
495 virtual STDMETHODIMP OnPlanRelatedBundleType(
496 __in_z LPCWSTR wzBundleId,
497 __in BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE recommendedType,
498 __inout BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE* pRequestedType,
499 __inout BOOL* pfCancel
500 )
501 {
502 // If we're only installing prerequisites, do not touch related bundles.
503 if (m_fPrereq)
504 {
505 *pRequestedType = BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_NONE;
506 }
507
508 return CBalBaseBootstrapperApplication::OnPlanRelatedBundleType(wzBundleId, recommendedType, pRequestedType, pfCancel);
509 }
510
511
512 virtual STDMETHODIMP OnPlanPackageBegin(
513 __in_z LPCWSTR wzPackageId,
514 __in BOOTSTRAPPER_PACKAGE_STATE state,
515 __in BOOL fCached,
516 __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition,
517 __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT repairCondition,
518 __in BOOTSTRAPPER_REQUEST_STATE recommendedState,
519 __in BOOTSTRAPPER_CACHE_TYPE recommendedCacheType,
520 __inout BOOTSTRAPPER_REQUEST_STATE* pRequestState,
521 __inout BOOTSTRAPPER_CACHE_TYPE* pRequestedCacheType,
522 __inout BOOL* pfCancel
523 )
524 {
525 HRESULT hr = S_OK;
526 BAL_INFO_PACKAGE* pPackage = NULL;
527
528 // If we're planning to install prerequisites, install them. The prerequisites need to be installed
529 // in all cases (even uninstall!) so the BA can load next.
530 if (m_fPrereq)
531 {
532 // Only install prerequisite packages, and check the InstallCondition on them.
533 BOOL fInstall = FALSE;
534
535 hr = BalInfoFindPackageById(&m_Bundle.packages, wzPackageId, &pPackage);
536 if (SUCCEEDED(hr) && pPackage->fPrereqPackage)
537 {
538 fInstall = BOOTSTRAPPER_PACKAGE_CONDITION_FALSE != installCondition;
539 }
540
541 if (fInstall)
542 {
543 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_PRESENT;
544 }
545 else
546 {
547 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE;
548 }
549
550 // Don't force cache packages while installing prerequisites.
551 if (BOOTSTRAPPER_CACHE_TYPE_FORCE == *pRequestedCacheType)
552 {
553 *pRequestedCacheType = BOOTSTRAPPER_CACHE_TYPE_KEEP;
554 }
555 }
556 else if (m_sczAfterForcedRestartPackage) // after force restart, skip packages until after the package that caused the restart.
557 {
558 // After restart we need to finish the dependency registration for our package so allow the package
559 // to go present.
560 if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, wzPackageId, -1, m_sczAfterForcedRestartPackage, -1))
561 {
562 // Do not allow a repair because that could put us in a perpetual restart loop.
563 if (BOOTSTRAPPER_REQUEST_STATE_REPAIR == *pRequestState)
564 {
565 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_PRESENT;
566 }
567
568 ReleaseNullStr(m_sczAfterForcedRestartPackage); // no more skipping now.
569 }
570 else // not the matching package, so skip it.
571 {
572 BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Skipping package: %ls, after restart because it was applied before the restart.", wzPackageId);
573
574 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE;
575 }
576 }
577
578 return CBalBaseBootstrapperApplication::OnPlanPackageBegin(wzPackageId, state, fCached, installCondition, repairCondition, recommendedState, recommendedCacheType, pRequestState, pRequestedCacheType, pfCancel);
579 }
580
581
582 virtual STDMETHODIMP OnPlanMsiPackage(
583 __in_z LPCWSTR wzPackageId,
584 __in BOOL fExecute,
585 __in BOOTSTRAPPER_ACTION_STATE action,
586 __in BOOTSTRAPPER_MSI_FILE_VERSIONING recommendedFileVersioning,
587 __inout BOOL* pfCancel,
588 __inout BURN_MSI_PROPERTY* pActionMsiProperty,
589 __inout INSTALLUILEVEL* pUiLevel,
590 __inout BOOL* pfDisableExternalUiHandler,
591 __inout BOOTSTRAPPER_MSI_FILE_VERSIONING* pFileVersioning
592 )
593 {
594 HRESULT hr = S_OK;
595 BAL_INFO_PACKAGE* pPackage = NULL;
596 BOOL fShowInternalUI = FALSE;
597 INSTALLUILEVEL uiLevel = INSTALLUILEVEL_NOCHANGE;
598
599 switch (m_command.display)
600 {
601 case BOOTSTRAPPER_DISPLAY_FULL:
602 uiLevel = INSTALLUILEVEL_FULL;
603 break;
604
605 case BOOTSTRAPPER_DISPLAY_PASSIVE:
606 uiLevel = INSTALLUILEVEL_REDUCED;
607 break;
608 }
609
610 if (INSTALLUILEVEL_NOCHANGE != uiLevel)
611 {
612 hr = BalInfoFindPackageById(&m_Bundle.packages, wzPackageId, &pPackage);
613 if (SUCCEEDED(hr) && pPackage->sczDisplayInternalUICondition)
614 {
615 hr = BalEvaluateCondition(pPackage->sczDisplayInternalUICondition, &fShowInternalUI);
616 BalExitOnFailure(hr, "Failed to evaluate condition for package '%ls': %ls", wzPackageId, pPackage->sczDisplayInternalUICondition);
617
618 if (fShowInternalUI)
619 {
620 *pUiLevel = uiLevel;
621 }
622 }
623 }
624
625 LExit:
626 return __super::OnPlanMsiPackage(wzPackageId, fExecute, action, recommendedFileVersioning, pfCancel, pActionMsiProperty, pUiLevel, pfDisableExternalUiHandler, pFileVersioning);
627 }
628
629
630 virtual STDMETHODIMP OnPlannedPackage(
631 __in_z LPCWSTR wzPackageId,
632 __in BOOTSTRAPPER_ACTION_STATE execute,
633 __in BOOTSTRAPPER_ACTION_STATE rollback,
634 __in BOOL fPlannedCache,
635 __in BOOL fPlannedUncache
636 )
637 {
638 if (m_fPrereq && BOOTSTRAPPER_ACTION_STATE_NONE != execute)
639 {
640 m_fPrereqPackagePlanned = TRUE;
641 }
642
643 return __super::OnPlannedPackage(wzPackageId, execute, rollback, fPlannedCache, fPlannedUncache);
644 }
645
646
647 virtual STDMETHODIMP OnPlanComplete(
648 __in HRESULT hrStatus
649 )
650 {
651 HRESULT hr = S_OK;
652 BOOL fPreplannedPrereqs = WIXSTDBA_STATE_PLANNING_PREREQS == m_state;
653 WIXSTDBA_STATE completedState = WIXSTDBA_STATE_PLANNED;
654 BOOL fApply = TRUE;
655
656 if (fPreplannedPrereqs)
657 {
658 if (SUCCEEDED(hrStatus) && !m_fPrereqPackagePlanned)
659 {
660 // Nothing to do, so close and let the parent BA take over.
661 m_fPrereqSkipped = TRUE;
662 SetState(WIXSTDBA_STATE_APPLIED, S_OK);
663 ExitFunction();
664 }
665 else if (BOOTSTRAPPER_ACTION_HELP == m_command.action)
666 {
667 // If prereq packages were planned then the managed BA probably can't be loaded, so show the help from this BA.
668
669 // Need to force the state change since normally moving backwards is prevented.
670 ::PostMessageW(m_hWnd, WM_WIXSTDBA_CHANGE_STATE, 0, WIXSTDBA_STATE_HELP);
671
672 ::PostMessageW(m_hWnd, WM_WIXSTDBA_SHOW_HELP, 0, 0);
673
674 ExitFunction();
675 }
676
677 completedState = WIXSTDBA_STATE_PLANNED_PREREQS;
678 }
679
680 SetState(completedState, hrStatus);
681
682 if (FAILED(hrStatus))
683 {
684 ExitFunction();
685 }
686
687 if (fPreplannedPrereqs)
688 {
689 // If the UI should be visible, display it now and hide the splash screen
690 if (BOOTSTRAPPER_DISPLAY_NONE < m_command.display)
691 {
692 ::ShowWindow(m_pTheme->hwndParent, SW_SHOW);
693 }
694
695 m_pEngine->CloseSplashScreen();
696
697 fApply = BOOTSTRAPPER_DISPLAY_FULL > m_command.display ||
698 BOOTSTRAPPER_RESUME_TYPE_REBOOT == m_command.resumeType;
699 }
700
701 if (fApply)
702 {
703 ::PostMessageW(m_hWnd, WM_WIXSTDBA_APPLY_PACKAGES, 0, 0);
704 }
705
706 LExit:
707 return hr;
708 }
709
710
711 virtual STDMETHODIMP OnApplyBegin(
712 __in DWORD dwPhaseCount,
713 __in BOOL* pfCancel
714 )
715 {
716 m_fStartedExecution = FALSE;
717 m_dwCalculatedCacheProgress = 0;
718 m_dwCalculatedExecuteProgress = 0;
719 m_nLastMsiFilesInUseResult = IDNOACTION;
720 m_nLastNetfxFilesInUseResult = IDNOACTION;
721
722 return __super::OnApplyBegin(dwPhaseCount, pfCancel);
723 }
724
725
726 virtual STDMETHODIMP OnPauseAutomaticUpdatesBegin(
727 )
728 {
729 HRESULT hr = S_OK;
730 LOC_STRING* pLocString = NULL;
731 LPWSTR sczFormattedString = NULL;
732 LPCWSTR wz = NULL;
733
734 hr = __super::OnPauseAutomaticUpdatesBegin();
735
736 LocGetString(m_pWixLoc, L"#(loc.PauseAutomaticUpdatesMessage)", &pLocString);
737
738 if (pLocString)
739 {
740 BalFormatString(pLocString->wzText, &sczFormattedString);
741 }
742
743 wz = sczFormattedString ? sczFormattedString : L"Pausing Windows automatic updates";
744
745 ThemeSetTextControl(m_pControlOverallProgressPackageText, wz);
746
747 ReleaseStr(sczFormattedString);
748 return hr;
749 }
750
751
752 virtual STDMETHODIMP OnSystemRestorePointBegin(
753 )
754 {
755 HRESULT hr = S_OK;
756 LOC_STRING* pLocString = NULL;
757 LPWSTR sczFormattedString = NULL;
758 LPCWSTR wz = NULL;
759
760 hr = __super::OnSystemRestorePointBegin();
761
762 LocGetString(m_pWixLoc, L"#(loc.SystemRestorePointMessage)", &pLocString);
763
764 if (pLocString)
765 {
766 BalFormatString(pLocString->wzText, &sczFormattedString);
767 }
768
769 wz = sczFormattedString ? sczFormattedString : L"Creating system restore point";
770
771 ThemeSetTextControl(m_pControlOverallProgressPackageText, wz);
772
773 ReleaseStr(sczFormattedString);
774 return hr;
775 }
776
777
778 virtual STDMETHODIMP OnCachePackageBegin(
779 __in_z LPCWSTR wzPackageId,
780 __in DWORD cCachePayloads,
781 __in DWORD64 dw64PackageCacheSize,
782 __in BOOL fVital,
783 __inout BOOL* pfCancel
784 )
785 {
786 if (wzPackageId && *wzPackageId)
787 {
788 BAL_INFO_PACKAGE* pPackage = NULL;
789 HRESULT hr = BalInfoFindPackageById(&m_Bundle.packages, wzPackageId, &pPackage);
790 LPCWSTR wz = (SUCCEEDED(hr) && pPackage->sczDisplayName) ? pPackage->sczDisplayName : wzPackageId;
791
792 ThemeSetTextControl(m_pControlCacheProgressPackageText, wz);
793
794 // If something started executing, leave it in the overall progress text.
795 if (!m_fStartedExecution)
796 {
797 ThemeSetTextControl(m_pControlOverallProgressPackageText, wz);
798 }
799 }
800
801 return __super::OnCachePackageBegin(wzPackageId, cCachePayloads, dw64PackageCacheSize, fVital, pfCancel);
802 }
803
804
805 virtual STDMETHODIMP OnCacheAcquireProgress(
806 __in_z LPCWSTR wzPackageOrContainerId,
807 __in_z_opt LPCWSTR wzPayloadId,
808 __in DWORD64 dw64Progress,
809 __in DWORD64 dw64Total,
810 __in DWORD dwOverallPercentage,
811 __inout BOOL* pfCancel
812 )
813 {
814#ifdef DEBUG
815 BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "WIXSTDBA: OnCacheAcquireProgress() - container/package: %ls, payload: %ls, progress: %I64u, total: %I64u, overall progress: %u%%", wzPackageOrContainerId, wzPayloadId, dw64Progress, dw64Total, dwOverallPercentage);
816#endif
817
818 UpdateCacheProgress(dwOverallPercentage);
819
820 return __super::OnCacheAcquireProgress(wzPackageOrContainerId, wzPayloadId, dw64Progress, dw64Total, dwOverallPercentage, pfCancel);
821 }
822
823
824 virtual STDMETHODIMP OnCacheContainerOrPayloadVerifyProgress(
825 __in_z LPCWSTR wzPackageOrContainerId,
826 __in_z_opt LPCWSTR wzPayloadId,
827 __in DWORD64 dw64Progress,
828 __in DWORD64 dw64Total,
829 __in DWORD dwOverallPercentage,
830 __inout BOOL* pfCancel
831 )
832 {
833#ifdef DEBUG
834 BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "WIXSTDBA: OnCacheContainerOrPayloadVerifyProgress() - container/package: %ls, payload: %ls, progress: %I64u, total: %I64u, overall progress: %u%%", wzPackageOrContainerId, wzPayloadId, dw64Progress, dw64Total, dwOverallPercentage);
835#endif
836
837 UpdateCacheProgress(dwOverallPercentage);
838
839 return __super::OnCacheContainerOrPayloadVerifyProgress(wzPackageOrContainerId, wzPayloadId, dw64Progress, dw64Total, dwOverallPercentage, pfCancel);
840 }
841
842
843 virtual STDMETHODIMP OnCachePayloadExtractProgress(
844 __in_z LPCWSTR wzPackageOrContainerId,
845 __in_z_opt LPCWSTR wzPayloadId,
846 __in DWORD64 dw64Progress,
847 __in DWORD64 dw64Total,
848 __in DWORD dwOverallPercentage,
849 __inout BOOL* pfCancel
850 )
851 {
852#ifdef DEBUG
853 BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "WIXSTDBA: OnCachePayloadExtractProgress() - container/package: %ls, payload: %ls, progress: %I64u, total: %I64u, overall progress: %u%%", wzPackageOrContainerId, wzPayloadId, dw64Progress, dw64Total, dwOverallPercentage);
854#endif
855
856 UpdateCacheProgress(dwOverallPercentage);
857
858 return __super::OnCachePayloadExtractProgress(wzPackageOrContainerId, wzPayloadId, dw64Progress, dw64Total, dwOverallPercentage, pfCancel);
859 }
860
861
862 virtual STDMETHODIMP OnCacheVerifyProgress(
863 __in_z LPCWSTR wzPackageOrContainerId,
864 __in_z_opt LPCWSTR wzPayloadId,
865 __in DWORD64 dw64Progress,
866 __in DWORD64 dw64Total,
867 __in DWORD dwOverallPercentage,
868 __in BOOTSTRAPPER_CACHE_VERIFY_STEP verifyStep,
869 __inout BOOL* pfCancel
870 )
871 {
872#ifdef DEBUG
873 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);
874#endif
875
876 UpdateCacheProgress(dwOverallPercentage);
877
878 return __super::OnCacheVerifyProgress(wzPackageOrContainerId, wzPayloadId, dw64Progress, dw64Total, dwOverallPercentage, verifyStep, pfCancel);
879 }
880
881
882 virtual STDMETHODIMP OnCacheAcquireComplete(
883 __in_z LPCWSTR wzPackageOrContainerId,
884 __in_z_opt LPCWSTR wzPayloadId,
885 __in HRESULT hrStatus,
886 __in BOOTSTRAPPER_CACHEACQUIRECOMPLETE_ACTION recommendation,
887 __inout BOOTSTRAPPER_CACHEACQUIRECOMPLETE_ACTION* pAction
888 )
889 {
890 SetProgressState(hrStatus);
891 return __super::OnCacheAcquireComplete(wzPackageOrContainerId, wzPayloadId, hrStatus, recommendation, pAction);
892 }
893
894
895 virtual STDMETHODIMP OnCacheContainerOrPayloadVerifyComplete(
896 __in_z LPCWSTR wzPackageOrContainerId,
897 __in_z_opt LPCWSTR wzPayloadId,
898 __in HRESULT hrStatus
899 )
900 {
901 SetProgressState(hrStatus);
902 return __super::OnCacheContainerOrPayloadVerifyComplete(wzPackageOrContainerId, wzPayloadId, hrStatus);
903 }
904
905
906 virtual STDMETHODIMP OnCachePayloadExtractComplete(
907 __in_z LPCWSTR wzPackageOrContainerId,
908 __in_z_opt LPCWSTR wzPayloadId,
909 __in HRESULT hrStatus
910 )
911 {
912 SetProgressState(hrStatus);
913 return __super::OnCachePayloadExtractComplete(wzPackageOrContainerId, wzPayloadId, hrStatus);
914 }
915
916
917 virtual STDMETHODIMP OnCacheVerifyComplete(
918 __in_z LPCWSTR wzPackageId,
919 __in_z LPCWSTR wzPayloadId,
920 __in HRESULT hrStatus,
921 __in BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION recommendation,
922 __inout BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION* pAction
923 )
924 {
925 SetProgressState(hrStatus);
926 return __super::OnCacheVerifyComplete(wzPackageId, wzPayloadId, hrStatus, recommendation, pAction);
927 }
928
929
930 virtual STDMETHODIMP OnCacheComplete(
931 __in HRESULT hrStatus
932 )
933 {
934 UpdateCacheProgress(SUCCEEDED(hrStatus) ? 100 : 0);
935 ThemeSetTextControl(m_pControlCacheProgressPackageText, L"");
936 SetState(WIXSTDBA_STATE_CACHED, S_OK); // we always return success here and let OnApplyComplete() deal with the error.
937 return __super::OnCacheComplete(hrStatus);
938 }
939
940
941 virtual STDMETHODIMP OnError(
942 __in BOOTSTRAPPER_ERROR_TYPE errorType,
943 __in LPCWSTR wzPackageId,
944 __in DWORD dwCode,
945 __in_z LPCWSTR wzError,
946 __in DWORD dwUIHint,
947 __in DWORD cData,
948 __in_ecount_z_opt(cData) LPCWSTR* rgwzData,
949 __in int nRecommendation,
950 __inout int* pResult
951 )
952 {
953#ifdef DEBUG
954 BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "WIXSTDBA: OnError() - package: %ls, code: %d, ui hint: %d, message: %ls", wzPackageId, dwCode, dwUIHint, wzError);
955#endif
956
957 HRESULT hr = S_OK;
958 int nResult = *pResult;
959 LPWSTR sczError = NULL;
960
961 if (BOOTSTRAPPER_DISPLAY_EMBEDDED == m_command.display)
962 {
963 hr = m_pEngine->SendEmbeddedError(dwCode, wzError, dwUIHint, &nResult);
964 if (FAILED(hr))
965 {
966 nResult = IDERROR;
967 }
968 }
969 else if (BOOTSTRAPPER_DISPLAY_FULL == m_command.display)
970 {
971 // If this is an authentication failure, let the engine try to handle it for us.
972 if (BOOTSTRAPPER_ERROR_TYPE_HTTP_AUTH_SERVER == errorType || BOOTSTRAPPER_ERROR_TYPE_HTTP_AUTH_PROXY == errorType)
973 {
974 nResult = IDTRYAGAIN;
975 }
976 else // show a generic error message box.
977 {
978 BalRetryErrorOccurred(wzPackageId, dwCode);
979
980 if (!m_fShowingInternalUiThisPackage)
981 {
982 // If no error message was provided, use the error code to try and get an error message.
983 if (!wzError || !*wzError || BOOTSTRAPPER_ERROR_TYPE_WINDOWS_INSTALLER != errorType)
984 {
985 hr = StrAllocFromError(&sczError, dwCode, NULL);
986 if (FAILED(hr) || !sczError || !*sczError)
987 {
988 StrAllocFormatted(&sczError, L"0x%x", dwCode);
989 }
990
991 hr = S_OK;
992 }
993
994 nResult = ::MessageBoxW(m_hWnd, sczError ? sczError : wzError, m_pTheme->sczCaption, dwUIHint);
995 }
996 }
997
998 SetProgressState(HRESULT_FROM_WIN32(dwCode));
999 }
1000 else // just take note of the error code and let things continue.
1001 {
1002 BalRetryErrorOccurred(wzPackageId, dwCode);
1003 }
1004
1005 ReleaseStr(sczError);
1006
1007 *pResult = nResult;
1008
1009#ifdef DEBUG
1010 BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "WIXSTDBA: OnError() - package: %ls, hr: 0x%0x, result: %d", wzPackageId, hr, nResult);
1011#endif
1012
1013 return FAILED(hr) ? hr : __super::OnError(errorType, wzPackageId, dwCode, wzError, dwUIHint, cData, rgwzData, nRecommendation, pResult);
1014 }
1015
1016
1017 virtual STDMETHODIMP OnExecuteMsiMessage(
1018 __in_z LPCWSTR wzPackageId,
1019 __in INSTALLMESSAGE messageType,
1020 __in DWORD dwUIHint,
1021 __in_z LPCWSTR wzMessage,
1022 __in DWORD cData,
1023 __in_ecount_z_opt(cData) LPCWSTR* rgwzData,
1024 __in int nRecommendation,
1025 __inout int* pResult
1026 )
1027 {
1028#ifdef DEBUG
1029 BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "WIXSTDBA: OnExecuteMsiMessage() - package: %ls, message: %ls", wzPackageId, wzMessage);
1030#endif
1031
1032 if (BOOTSTRAPPER_DISPLAY_FULL == m_command.display && (INSTALLMESSAGE_WARNING == messageType || INSTALLMESSAGE_USER == messageType))
1033 {
1034 if (!m_fShowingInternalUiThisPackage)
1035 {
1036 int nResult = ::MessageBoxW(m_hWnd, wzMessage, m_pTheme->sczCaption, dwUIHint);
1037
1038 *pResult = nResult;
1039
1040 return __super::OnExecuteMsiMessage(wzPackageId, messageType, dwUIHint, wzMessage, cData, rgwzData, nRecommendation, pResult);
1041 }
1042 }
1043
1044 if (INSTALLMESSAGE_ACTIONSTART == messageType)
1045 {
1046 ThemeSetTextControl(m_pControlExecuteProgressActionDataText, wzMessage);
1047 }
1048
1049 return __super::OnExecuteMsiMessage(wzPackageId, messageType, dwUIHint, wzMessage, cData, rgwzData, nRecommendation, pResult);
1050 }
1051
1052
1053 virtual STDMETHODIMP OnProgress(
1054 __in DWORD dwProgressPercentage,
1055 __in DWORD dwOverallProgressPercentage,
1056 __inout BOOL* pfCancel
1057 )
1058 {
1059 WCHAR wzProgress[5] = { };
1060
1061#ifdef DEBUG
1062 BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "WIXSTDBA: OnProgress() - progress: %u%%, overall progress: %u%%", dwProgressPercentage, dwOverallProgressPercentage);
1063#endif
1064
1065 ::StringCchPrintfW(wzProgress, countof(wzProgress), L"%u%%", dwOverallProgressPercentage);
1066 ThemeSetTextControl(m_pControlOverallProgressText, wzProgress);
1067
1068 ThemeSetProgressControl(m_pControlOverallProgressbar, dwOverallProgressPercentage);
1069 SetTaskbarButtonProgress(dwOverallProgressPercentage);
1070
1071 return __super::OnProgress(dwProgressPercentage, dwOverallProgressPercentage, pfCancel);
1072 }
1073
1074
1075 virtual STDMETHODIMP OnExecutePackageBegin(
1076 __in_z LPCWSTR wzPackageId,
1077 __in BOOL fExecute,
1078 __in BOOTSTRAPPER_ACTION_STATE action,
1079 __in INSTALLUILEVEL uiLevel,
1080 __in BOOL fDisableExternalUiHandler,
1081 __inout BOOL* pfCancel
1082 )
1083 {
1084 HRESULT hr = S_OK;
1085 LPWSTR sczFormattedString = NULL;
1086 BOOL fShowingInternalUiThisPackage = FALSE;
1087
1088 m_fStartedExecution = TRUE;
1089
1090 if (wzPackageId && *wzPackageId)
1091 {
1092 BAL_INFO_PACKAGE* pPackage = NULL;
1093 BalInfoFindPackageById(&m_Bundle.packages, wzPackageId, &pPackage);
1094
1095 LPCWSTR wz = wzPackageId;
1096 if (pPackage)
1097 {
1098 LOC_STRING* pLocString = NULL;
1099
1100 switch (pPackage->type)
1101 {
1102 case BAL_INFO_PACKAGE_TYPE_BUNDLE_ADDON:
1103 LocGetString(m_pWixLoc, L"#(loc.ExecuteAddonRelatedBundleMessage)", &pLocString);
1104 break;
1105
1106 case BAL_INFO_PACKAGE_TYPE_BUNDLE_PATCH:
1107 LocGetString(m_pWixLoc, L"#(loc.ExecutePatchRelatedBundleMessage)", &pLocString);
1108 break;
1109
1110 case BAL_INFO_PACKAGE_TYPE_BUNDLE_UPGRADE:
1111 LocGetString(m_pWixLoc, L"#(loc.ExecuteUpgradeRelatedBundleMessage)", &pLocString);
1112 break;
1113 }
1114
1115 if (pLocString)
1116 {
1117 // If the wix developer is showing a hidden variable in the UI, then obviously they don't care about keeping it safe
1118 // so don't go down the rabbit hole of making sure that this is securely freed.
1119 BalFormatString(pLocString->wzText, &sczFormattedString);
1120 }
1121
1122 wz = sczFormattedString ? sczFormattedString : pPackage->sczDisplayName ? pPackage->sczDisplayName : wzPackageId;
1123 }
1124
1125 fShowingInternalUiThisPackage = INSTALLUILEVEL_NONE != (INSTALLUILEVEL_NONE & uiLevel);
1126
1127 ThemeSetTextControl(m_pControlExecuteProgressPackageText, wz);
1128 ThemeSetTextControl(m_pControlOverallProgressPackageText, wz);
1129 }
1130
1131 ::EnterCriticalSection(&m_csShowingInternalUiThisPackage);
1132 m_fShowingInternalUiThisPackage = fShowingInternalUiThisPackage;
1133 hr = __super::OnExecutePackageBegin(wzPackageId, fExecute, action, uiLevel, fDisableExternalUiHandler, pfCancel);
1134 ::LeaveCriticalSection(&m_csShowingInternalUiThisPackage);
1135
1136 ReleaseStr(sczFormattedString);
1137 return hr;
1138 }
1139
1140
1141 virtual STDMETHODIMP OnExecuteProgress(
1142 __in_z LPCWSTR wzPackageId,
1143 __in DWORD dwProgressPercentage,
1144 __in DWORD dwOverallProgressPercentage,
1145 __inout BOOL* pfCancel
1146 )
1147 {
1148 WCHAR wzProgress[5] = { };
1149
1150#ifdef DEBUG
1151 BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "WIXSTDBA: OnExecuteProgress() - package: %ls, progress: %u%%, overall progress: %u%%", wzPackageId, dwProgressPercentage, dwOverallProgressPercentage);
1152#endif
1153
1154 ::StringCchPrintfW(wzProgress, countof(wzProgress), L"%u%%", dwOverallProgressPercentage);
1155 ThemeSetTextControl(m_pControlExecuteProgressText, wzProgress);
1156
1157 ThemeSetProgressControl(m_pControlExecuteProgressbar, dwOverallProgressPercentage);
1158
1159 m_dwCalculatedExecuteProgress = dwOverallProgressPercentage * (100 - WIXSTDBA_ACQUIRE_PERCENTAGE) / 100;
1160 ThemeSetProgressControl(m_pControlOverallCalculatedProgressbar, m_dwCalculatedCacheProgress + m_dwCalculatedExecuteProgress);
1161
1162 SetTaskbarButtonProgress(m_dwCalculatedCacheProgress + m_dwCalculatedExecuteProgress);
1163
1164 return __super::OnExecuteProgress(wzPackageId, dwProgressPercentage, dwOverallProgressPercentage, pfCancel);
1165 }
1166
1167
1168 virtual STDMETHODIMP OnExecuteFilesInUse(
1169 __in_z LPCWSTR wzPackageId,
1170 __in DWORD cFiles,
1171 __in_ecount_z(cFiles) LPCWSTR* rgwzFiles,
1172 __in int nRecommendation,
1173 __in BOOTSTRAPPER_FILES_IN_USE_TYPE source,
1174 __inout int* pResult
1175 )
1176 {
1177
1178 if (!m_fShowingInternalUiThisPackage && wzPackageId && *wzPackageId)
1179 {
1180 BalLog(BOOTSTRAPPER_LOG_LEVEL_VERBOSE, "Package %ls has %d applications holding files in use.", wzPackageId, cFiles);
1181
1182 switch (source)
1183 {
1184 case BOOTSTRAPPER_FILES_IN_USE_TYPE_MSI:
1185 if (m_fShowStandardFilesInUse)
1186 {
1187 return ShowMsiFilesInUse(cFiles, rgwzFiles, source, pResult);
1188 }
1189 break;
1190 case BOOTSTRAPPER_FILES_IN_USE_TYPE_MSI_RM:
1191 if (m_fShowRMFilesInUse)
1192 {
1193 return ShowMsiFilesInUse(cFiles, rgwzFiles, source, pResult);
1194 }
1195 break;
1196 case BOOTSTRAPPER_FILES_IN_USE_TYPE_NETFX:
1197 if (m_fShowNetfxFilesInUse)
1198 {
1199 return ShowNetfxFilesInUse(cFiles, rgwzFiles, pResult);
1200 }
1201 break;
1202 }
1203 }
1204
1205 return __super::OnExecuteFilesInUse(wzPackageId, cFiles, rgwzFiles, nRecommendation, source, pResult);
1206 }
1207
1208
1209 virtual STDMETHODIMP OnExecutePackageComplete(
1210 __in_z LPCWSTR wzPackageId,
1211 __in HRESULT hrStatus,
1212 __in BOOTSTRAPPER_APPLY_RESTART restart,
1213 __in BOOTSTRAPPER_EXECUTEPACKAGECOMPLETE_ACTION recommendation,
1214 __inout BOOTSTRAPPER_EXECUTEPACKAGECOMPLETE_ACTION* pAction
1215 )
1216 {
1217 HRESULT hr = S_OK;
1218 SetProgressState(hrStatus);
1219
1220 hr = __super::OnExecutePackageComplete(wzPackageId, hrStatus, restart, recommendation, pAction);
1221
1222 if (m_fPrereq && BOOTSTRAPPER_APPLY_RESTART_NONE != restart)
1223 {
1224 BAL_INFO_PACKAGE* pPackage = NULL;
1225 HRESULT hrPrereq = BalInfoFindPackageById(&m_Bundle.packages, wzPackageId, &pPackage);
1226
1227 // If the prerequisite required a restart (any restart) then do an immediate
1228 // restart to ensure that the bundle will get launched again post reboot.
1229 if (SUCCEEDED(hrPrereq) && pPackage->fPrereqPackage)
1230 {
1231 *pAction = BOOTSTRAPPER_EXECUTEPACKAGECOMPLETE_ACTION_RESTART;
1232 }
1233 }
1234
1235 return hr;
1236 }
1237
1238
1239 virtual STDMETHODIMP OnExecuteComplete(
1240 __in HRESULT hrStatus
1241 )
1242 {
1243 HRESULT hr = S_OK;
1244
1245 ThemeSetTextControl(m_pControlExecuteProgressPackageText, L"");
1246 ThemeSetTextControl(m_pControlExecuteProgressActionDataText, L"");
1247 ThemeSetTextControl(m_pControlOverallProgressPackageText, L"");
1248 ThemeControlEnable(m_pControlProgressCancelButton, FALSE); // no more cancel.
1249 m_fShowingInternalUiThisPackage = FALSE;
1250
1251 SetState(WIXSTDBA_STATE_EXECUTED, S_OK); // we always return success here and let OnApplyComplete() deal with the error.
1252 SetProgressState(hrStatus);
1253
1254 return hr;
1255 }
1256
1257
1258 virtual STDMETHODIMP OnCacheAcquireResolving(
1259 __in_z_opt LPCWSTR wzPackageOrContainerId,
1260 __in_z_opt LPCWSTR wzPayloadId,
1261 __in_z LPCWSTR* rgSearchPaths,
1262 __in DWORD /*cSearchPaths*/,
1263 __in BOOL /*fFoundLocal*/,
1264 __in DWORD dwRecommendedSearchPath,
1265 __in_z_opt LPCWSTR /*wzDownloadUrl*/,
1266 __in_z_opt LPCWSTR /*wzPayloadContainerId*/,
1267 __in BOOTSTRAPPER_CACHE_RESOLVE_OPERATION /*recommendation*/,
1268 __inout DWORD* /*pdwChosenSearchPath*/,
1269 __inout BOOTSTRAPPER_CACHE_RESOLVE_OPERATION* pAction,
1270 __inout BOOL* pfCancel
1271 )
1272 {
1273 HRESULT hr = S_OK;
1274 LPWSTR sczPath = NULL;
1275
1276 if (BOOTSTRAPPER_CACHE_RESOLVE_NONE == *pAction && BOOTSTRAPPER_DISPLAY_FULL == m_command.display) // prompt to change the source location.
1277 {
1278 static COMDLG_FILTERSPEC vrgFilters[] =
1279 {
1280 { L"All Files", L"*.*" },
1281 };
1282
1283 hr = WnduShowOpenFileDialog(m_hWnd, TRUE, TRUE, m_pTheme->sczCaption, vrgFilters, countof(vrgFilters), 1, rgSearchPaths[dwRecommendedSearchPath], &sczPath);
1284 if (SUCCEEDED(hr))
1285 {
1286 hr = m_pEngine->SetLocalSource(wzPackageOrContainerId, wzPayloadId, sczPath);
1287 *pAction = BOOTSTRAPPER_CACHE_RESOLVE_RETRY;
1288 }
1289 else
1290 {
1291 *pfCancel = TRUE;
1292 }
1293 }
1294 // else there's nothing more we can do in non-interactive mode
1295
1296 *pfCancel |= CheckCanceled();
1297
1298 ReleaseStr(sczPath);
1299
1300 return hr;
1301 }
1302
1303 virtual STDMETHODIMP OnApplyComplete(
1304 __in HRESULT hrStatus,
1305 __in BOOTSTRAPPER_APPLY_RESTART restart,
1306 __in BOOTSTRAPPER_APPLYCOMPLETE_ACTION recommendation,
1307 __inout BOOTSTRAPPER_APPLYCOMPLETE_ACTION* pAction
1308 )
1309 {
1310 HRESULT hr = S_OK;
1311
1312 __super::OnApplyComplete(hrStatus, restart, recommendation, pAction);
1313
1314 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.
1315 m_fRestartRequired = BOOTSTRAPPER_APPLY_RESTART_NONE != restart;
1316 BalSetStringVariable(WIXSTDBA_VARIABLE_RESTART_REQUIRED, m_fRestartRequired ? L"1" : NULL, FALSE);
1317
1318 m_fShouldRestart = m_fRestartRequired && BAL_INFO_RESTART_NEVER < m_BalInfoCommand.restart;
1319
1320 // Automatically restart if we're not displaying a UI or the command line said to always allow restarts.
1321 m_fAllowRestart = m_fShouldRestart && (BOOTSTRAPPER_DISPLAY_FULL > m_command.display || BAL_INFO_RESTART_PROMPT < m_BalInfoCommand.restart);
1322
1323 if (m_fPrereq)
1324 {
1325 m_fPrereqInstalled = SUCCEEDED(hrStatus);
1326 }
1327
1328 // If we are showing UI, wait a beat before moving to the final screen.
1329 if (BOOTSTRAPPER_DISPLAY_NONE < m_command.display)
1330 {
1331 ::Sleep(250);
1332 }
1333
1334 SetState(WIXSTDBA_STATE_APPLIED, hrStatus);
1335 SetTaskbarButtonProgress(100); // show full progress bar, green, yellow, or red
1336
1337 *pAction = BOOTSTRAPPER_APPLYCOMPLETE_ACTION_NONE;
1338
1339 return hr;
1340 }
1341
1342 virtual STDMETHODIMP OnLaunchApprovedExeComplete(
1343 __in HRESULT hrStatus,
1344 __in DWORD /*processId*/
1345 )
1346 {
1347 HRESULT hr = S_OK;
1348
1349 if (HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED) == hrStatus)
1350 {
1351 //try with ShelExec next time
1352 OnClickLaunchButton();
1353 }
1354 else
1355 {
1356 ::PostMessageW(m_hWnd, WM_CLOSE, 0, 0);
1357 }
1358
1359 return hr;
1360 }
1361
1362 virtual STDMETHODIMP OnSetUpdateComplete(
1363 __in HRESULT hrStatus,
1364 __in_z_opt LPCWSTR wzPreviousPackageId,
1365 __in_z_opt LPCWSTR wzNewPackageId
1366 )
1367 {
1368 BAL_INFO_PACKAGE* pPackage = NULL;
1369
1370 if (SUCCEEDED(hrStatus) && wzNewPackageId)
1371 {
1372 BalInfoAddUpdateBundleAsPackage(&m_Bundle.packages, wzNewPackageId, wzPreviousPackageId, &pPackage);
1373 // Best effort
1374 }
1375
1376 return S_OK;
1377 }
1378
1379
1380 virtual STDMETHODIMP OnElevateComplete(
1381 __in HRESULT hrStatus
1382 )
1383 {
1384 if (m_fElevatingForRestart)
1385 {
1386 m_fElevatingForRestart = FALSE;
1387
1388 if (SUCCEEDED(hrStatus))
1389 {
1390 m_fAllowRestart = TRUE;
1391
1392 ::SendMessageW(m_hWnd, WM_CLOSE, 0, 0);
1393 }
1394 // else if failed then OnError showed the user an error message box
1395 }
1396
1397 return __super::OnElevateComplete(hrStatus);
1398 }
1399
1400
1401 virtual STDMETHODIMP_(void) BAProcFallback(
1402 __in BOOTSTRAPPER_APPLICATION_MESSAGE message,
1403 __in const LPVOID pvArgs,
1404 __inout LPVOID pvResults,
1405 __inout HRESULT* phr,
1406 __in_opt LPVOID /*pvContext*/
1407 )
1408 {
1409 if (!m_pfnBAFunctionsProc || FAILED(*phr))
1410 {
1411 return;
1412 }
1413
1414 // Always log before and after so we don't get blamed when BAFunctions changes something.
1415 switch (message)
1416 {
1417 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTBEGIN:
1418 OnDetectBeginFallback(reinterpret_cast<BA_ONDETECTBEGIN_ARGS*>(pvArgs), reinterpret_cast<BA_ONDETECTBEGIN_RESULTS*>(pvResults));
1419 break;
1420 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTCOMPLETE:
1421 OnDetectCompleteFallback(reinterpret_cast<BA_ONDETECTCOMPLETE_ARGS*>(pvArgs), reinterpret_cast<BA_ONDETECTCOMPLETE_RESULTS*>(pvResults));
1422 break;
1423 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANBEGIN:
1424 OnPlanBeginFallback(reinterpret_cast<BA_ONPLANBEGIN_ARGS*>(pvArgs), reinterpret_cast<BA_ONPLANBEGIN_RESULTS*>(pvResults));
1425 break;
1426 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANCOMPLETE:
1427 OnPlanCompleteFallback(reinterpret_cast<BA_ONPLANCOMPLETE_ARGS*>(pvArgs), reinterpret_cast<BA_ONPLANCOMPLETE_RESULTS*>(pvResults));
1428 break;
1429 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONSTARTUP: // BAFunctions is loaded during this event on a separate thread so it's not possible to forward it.
1430 break;
1431 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONSHUTDOWN:
1432 OnShutdownFallback(reinterpret_cast<BA_ONSHUTDOWN_ARGS*>(pvArgs), reinterpret_cast<BA_ONSHUTDOWN_RESULTS*>(pvResults));
1433 break;
1434 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTFORWARDCOMPATIBLEBUNDLE:
1435 OnDetectForwardCompatibleBundleFallback(reinterpret_cast<BA_ONDETECTFORWARDCOMPATIBLEBUNDLE_ARGS*>(pvArgs), reinterpret_cast<BA_ONDETECTFORWARDCOMPATIBLEBUNDLE_RESULTS*>(pvResults));
1436 break;
1437 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTUPDATEBEGIN:
1438 OnDetectUpdateBeginFallback(reinterpret_cast<BA_ONDETECTUPDATEBEGIN_ARGS*>(pvArgs), reinterpret_cast<BA_ONDETECTUPDATEBEGIN_RESULTS*>(pvResults));
1439 break;
1440 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTUPDATE:
1441 OnDetectUpdateFallback(reinterpret_cast<BA_ONDETECTUPDATE_ARGS*>(pvArgs), reinterpret_cast<BA_ONDETECTUPDATE_RESULTS*>(pvResults));
1442 break;
1443 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTUPDATECOMPLETE:
1444 OnDetectUpdateCompleteFallback(reinterpret_cast<BA_ONDETECTUPDATECOMPLETE_ARGS*>(pvArgs), reinterpret_cast<BA_ONDETECTUPDATECOMPLETE_RESULTS*>(pvResults));
1445 break;
1446 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTRELATEDBUNDLE:
1447 OnDetectRelatedBundleFallback(reinterpret_cast<BA_ONDETECTRELATEDBUNDLE_ARGS*>(pvArgs), reinterpret_cast<BA_ONDETECTRELATEDBUNDLE_RESULTS*>(pvResults));
1448 break;
1449 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTPACKAGEBEGIN:
1450 OnDetectPackageBeginFallback(reinterpret_cast<BA_ONDETECTPACKAGEBEGIN_ARGS*>(pvArgs), reinterpret_cast<BA_ONDETECTPACKAGEBEGIN_RESULTS*>(pvResults));
1451 break;
1452 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTRELATEDMSIPACKAGE:
1453 OnDetectRelatedMsiPackageFallback(reinterpret_cast<BA_ONDETECTRELATEDMSIPACKAGE_ARGS*>(pvArgs), reinterpret_cast<BA_ONDETECTRELATEDMSIPACKAGE_RESULTS*>(pvResults));
1454 break;
1455 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTPATCHTARGET:
1456 OnDetectPatchTargetFallback(reinterpret_cast<BA_ONDETECTPATCHTARGET_ARGS*>(pvArgs), reinterpret_cast<BA_ONDETECTPATCHTARGET_RESULTS*>(pvResults));
1457 break;
1458 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTMSIFEATURE:
1459 OnDetectMsiFeatureFallback(reinterpret_cast<BA_ONDETECTMSIFEATURE_ARGS*>(pvArgs), reinterpret_cast<BA_ONDETECTMSIFEATURE_RESULTS*>(pvResults));
1460 break;
1461 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTPACKAGECOMPLETE:
1462 OnDetectPackageCompleteFallback(reinterpret_cast<BA_ONDETECTPACKAGECOMPLETE_ARGS*>(pvArgs), reinterpret_cast<BA_ONDETECTPACKAGECOMPLETE_RESULTS*>(pvResults));
1463 break;
1464 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANRELATEDBUNDLE:
1465 OnPlanRelatedBundleFallback(reinterpret_cast<BA_ONPLANRELATEDBUNDLE_ARGS*>(pvArgs), reinterpret_cast<BA_ONPLANRELATEDBUNDLE_RESULTS*>(pvResults));
1466 break;
1467 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANPACKAGEBEGIN:
1468 OnPlanPackageBeginFallback(reinterpret_cast<BA_ONPLANPACKAGEBEGIN_ARGS*>(pvArgs), reinterpret_cast<BA_ONPLANPACKAGEBEGIN_RESULTS*>(pvResults));
1469 break;
1470 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANPATCHTARGET:
1471 OnPlanPatchTargetFallback(reinterpret_cast<BA_ONPLANPATCHTARGET_ARGS*>(pvArgs), reinterpret_cast<BA_ONPLANPATCHTARGET_RESULTS*>(pvResults));
1472 break;
1473 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANMSIFEATURE:
1474 OnPlanMsiFeatureFallback(reinterpret_cast<BA_ONPLANMSIFEATURE_ARGS*>(pvArgs), reinterpret_cast<BA_ONPLANMSIFEATURE_RESULTS*>(pvResults));
1475 break;
1476 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANPACKAGECOMPLETE:
1477 OnPlanPackageCompleteFallback(reinterpret_cast<BA_ONPLANPACKAGECOMPLETE_ARGS*>(pvArgs), reinterpret_cast<BA_ONPLANPACKAGECOMPLETE_RESULTS*>(pvResults));
1478 break;
1479 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONAPPLYBEGIN:
1480 OnApplyBeginFallback(reinterpret_cast<BA_ONAPPLYBEGIN_ARGS*>(pvArgs), reinterpret_cast<BA_ONAPPLYBEGIN_RESULTS*>(pvResults));
1481 break;
1482 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONELEVATEBEGIN:
1483 OnElevateBeginFallback(reinterpret_cast<BA_ONELEVATEBEGIN_ARGS*>(pvArgs), reinterpret_cast<BA_ONELEVATEBEGIN_RESULTS*>(pvResults));
1484 break;
1485 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONELEVATECOMPLETE:
1486 OnElevateCompleteFallback(reinterpret_cast<BA_ONELEVATECOMPLETE_ARGS*>(pvArgs), reinterpret_cast<BA_ONELEVATECOMPLETE_RESULTS*>(pvResults));
1487 break;
1488 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONPROGRESS:
1489 OnProgressFallback(reinterpret_cast<BA_ONPROGRESS_ARGS*>(pvArgs), reinterpret_cast<BA_ONPROGRESS_RESULTS*>(pvResults));
1490 break;
1491 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONERROR:
1492 OnErrorFallback(reinterpret_cast<BA_ONERROR_ARGS*>(pvArgs), reinterpret_cast<BA_ONERROR_RESULTS*>(pvResults));
1493 break;
1494 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONREGISTERBEGIN:
1495 OnRegisterBeginFallback(reinterpret_cast<BA_ONREGISTERBEGIN_ARGS*>(pvArgs), reinterpret_cast<BA_ONREGISTERBEGIN_RESULTS*>(pvResults));
1496 break;
1497 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONREGISTERCOMPLETE:
1498 OnRegisterCompleteFallback(reinterpret_cast<BA_ONREGISTERCOMPLETE_ARGS*>(pvArgs), reinterpret_cast<BA_ONREGISTERCOMPLETE_RESULTS*>(pvResults));
1499 break;
1500 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEBEGIN:
1501 OnCacheBeginFallback(reinterpret_cast<BA_ONCACHEBEGIN_ARGS*>(pvArgs), reinterpret_cast<BA_ONCACHEBEGIN_RESULTS*>(pvResults));
1502 break;
1503 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEPACKAGEBEGIN:
1504 OnCachePackageBeginFallback(reinterpret_cast<BA_ONCACHEPACKAGEBEGIN_ARGS*>(pvArgs), reinterpret_cast<BA_ONCACHEPACKAGEBEGIN_RESULTS*>(pvResults));
1505 break;
1506 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEACQUIREBEGIN:
1507 OnCacheAcquireBeginFallback(reinterpret_cast<BA_ONCACHEACQUIREBEGIN_ARGS*>(pvArgs), reinterpret_cast<BA_ONCACHEACQUIREBEGIN_RESULTS*>(pvResults));
1508 break;
1509 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEACQUIREPROGRESS:
1510 OnCacheAcquireProgressFallback(reinterpret_cast<BA_ONCACHEACQUIREPROGRESS_ARGS*>(pvArgs), reinterpret_cast<BA_ONCACHEACQUIREPROGRESS_RESULTS*>(pvResults));
1511 break;
1512 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEACQUIRERESOLVING:
1513 OnCacheAcquireResolvingFallback(reinterpret_cast<BA_ONCACHEACQUIRERESOLVING_ARGS*>(pvArgs), reinterpret_cast<BA_ONCACHEACQUIRERESOLVING_RESULTS*>(pvResults));
1514 break;
1515 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEACQUIRECOMPLETE:
1516 OnCacheAcquireCompleteFallback(reinterpret_cast<BA_ONCACHEACQUIRECOMPLETE_ARGS*>(pvArgs), reinterpret_cast<BA_ONCACHEACQUIRECOMPLETE_RESULTS*>(pvResults));
1517 break;
1518 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEVERIFYBEGIN:
1519 OnCacheVerifyBeginFallback(reinterpret_cast<BA_ONCACHEVERIFYBEGIN_ARGS*>(pvArgs), reinterpret_cast<BA_ONCACHEVERIFYBEGIN_RESULTS*>(pvResults));
1520 break;
1521 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEVERIFYCOMPLETE:
1522 OnCacheVerifyCompleteFallback(reinterpret_cast<BA_ONCACHEVERIFYCOMPLETE_ARGS*>(pvArgs), reinterpret_cast<BA_ONCACHEVERIFYCOMPLETE_RESULTS*>(pvResults));
1523 break;
1524 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEPACKAGECOMPLETE:
1525 OnCachePackageCompleteFallback(reinterpret_cast<BA_ONCACHEPACKAGECOMPLETE_ARGS*>(pvArgs), reinterpret_cast<BA_ONCACHEPACKAGECOMPLETE_RESULTS*>(pvResults));
1526 break;
1527 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHECOMPLETE:
1528 OnCacheCompleteFallback(reinterpret_cast<BA_ONCACHECOMPLETE_ARGS*>(pvArgs), reinterpret_cast<BA_ONCACHECOMPLETE_RESULTS*>(pvResults));
1529 break;
1530 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEBEGIN:
1531 OnExecuteBeginFallback(reinterpret_cast<BA_ONEXECUTEBEGIN_ARGS*>(pvArgs), reinterpret_cast<BA_ONEXECUTEBEGIN_RESULTS*>(pvResults));
1532 break;
1533 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEPACKAGEBEGIN:
1534 OnExecutePackageBeginFallback(reinterpret_cast<BA_ONEXECUTEPACKAGEBEGIN_ARGS*>(pvArgs), reinterpret_cast<BA_ONEXECUTEPACKAGEBEGIN_RESULTS*>(pvResults));
1535 break;
1536 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEPATCHTARGET:
1537 OnExecutePatchTargetFallback(reinterpret_cast<BA_ONEXECUTEPATCHTARGET_ARGS*>(pvArgs), reinterpret_cast<BA_ONEXECUTEPATCHTARGET_RESULTS*>(pvResults));
1538 break;
1539 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEPROGRESS:
1540 OnExecuteProgressFallback(reinterpret_cast<BA_ONEXECUTEPROGRESS_ARGS*>(pvArgs), reinterpret_cast<BA_ONEXECUTEPROGRESS_RESULTS*>(pvResults));
1541 break;
1542 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEMSIMESSAGE:
1543 OnExecuteMsiMessageFallback(reinterpret_cast<BA_ONEXECUTEMSIMESSAGE_ARGS*>(pvArgs), reinterpret_cast<BA_ONEXECUTEMSIMESSAGE_RESULTS*>(pvResults));
1544 break;
1545 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEFILESINUSE:
1546 OnExecuteFilesInUseFallback(reinterpret_cast<BA_ONEXECUTEFILESINUSE_ARGS*>(pvArgs), reinterpret_cast<BA_ONEXECUTEFILESINUSE_RESULTS*>(pvResults));
1547 break;
1548 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEPACKAGECOMPLETE:
1549 OnExecutePackageCompleteFallback(reinterpret_cast<BA_ONEXECUTEPACKAGECOMPLETE_ARGS*>(pvArgs), reinterpret_cast<BA_ONEXECUTEPACKAGECOMPLETE_RESULTS*>(pvResults));
1550 break;
1551 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTECOMPLETE:
1552 OnExecuteCompleteFallback(reinterpret_cast<BA_ONEXECUTECOMPLETE_ARGS*>(pvArgs), reinterpret_cast<BA_ONEXECUTECOMPLETE_RESULTS*>(pvResults));
1553 break;
1554 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONUNREGISTERBEGIN:
1555 OnUnregisterBeginFallback(reinterpret_cast<BA_ONUNREGISTERBEGIN_ARGS*>(pvArgs), reinterpret_cast<BA_ONUNREGISTERBEGIN_RESULTS*>(pvResults));
1556 break;
1557 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONUNREGISTERCOMPLETE:
1558 OnUnregisterCompleteFallback(reinterpret_cast<BA_ONUNREGISTERCOMPLETE_ARGS*>(pvArgs), reinterpret_cast<BA_ONUNREGISTERCOMPLETE_RESULTS*>(pvResults));
1559 break;
1560 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONAPPLYCOMPLETE:
1561 OnApplyCompleteFallback(reinterpret_cast<BA_ONAPPLYCOMPLETE_ARGS*>(pvArgs), reinterpret_cast<BA_ONAPPLYCOMPLETE_RESULTS*>(pvResults));
1562 break;
1563 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONLAUNCHAPPROVEDEXEBEGIN:
1564 OnLaunchApprovedExeBeginFallback(reinterpret_cast<BA_ONLAUNCHAPPROVEDEXEBEGIN_ARGS*>(pvArgs), reinterpret_cast<BA_ONLAUNCHAPPROVEDEXEBEGIN_RESULTS*>(pvResults));
1565 break;
1566 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONLAUNCHAPPROVEDEXECOMPLETE:
1567 OnLaunchApprovedExeCompleteFallback(reinterpret_cast<BA_ONLAUNCHAPPROVEDEXECOMPLETE_ARGS*>(pvArgs), reinterpret_cast<BA_ONLAUNCHAPPROVEDEXECOMPLETE_RESULTS*>(pvResults));
1568 break;
1569 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANMSIPACKAGE:
1570 OnPlanMsiPackageFallback(reinterpret_cast<BA_ONPLANMSIPACKAGE_ARGS*>(pvArgs), reinterpret_cast<BA_ONPLANMSIPACKAGE_RESULTS*>(pvResults));
1571 break;
1572 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONBEGINMSITRANSACTIONBEGIN:
1573 OnBeginMsiTransactionBeginFallback(reinterpret_cast<BA_ONBEGINMSITRANSACTIONBEGIN_ARGS*>(pvArgs), reinterpret_cast<BA_ONBEGINMSITRANSACTIONBEGIN_RESULTS*>(pvResults));
1574 break;
1575 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONBEGINMSITRANSACTIONCOMPLETE:
1576 OnBeginMsiTransactionCompleteFallback(reinterpret_cast<BA_ONBEGINMSITRANSACTIONCOMPLETE_ARGS*>(pvArgs), reinterpret_cast<BA_ONBEGINMSITRANSACTIONCOMPLETE_RESULTS*>(pvResults));
1577 break;
1578 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONCOMMITMSITRANSACTIONBEGIN:
1579 OnCommitMsiTransactionBeginFallback(reinterpret_cast<BA_ONCOMMITMSITRANSACTIONBEGIN_ARGS*>(pvArgs), reinterpret_cast<BA_ONCOMMITMSITRANSACTIONBEGIN_RESULTS*>(pvResults));
1580 break;
1581 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONCOMMITMSITRANSACTIONCOMPLETE:
1582 OnCommitMsiTransactionCompleteFallback(reinterpret_cast<BA_ONCOMMITMSITRANSACTIONCOMPLETE_ARGS*>(pvArgs), reinterpret_cast<BA_ONCOMMITMSITRANSACTIONCOMPLETE_RESULTS*>(pvResults));
1583 break;
1584 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONROLLBACKMSITRANSACTIONBEGIN:
1585 OnRollbackMsiTransactionBeginFallback(reinterpret_cast<BA_ONROLLBACKMSITRANSACTIONBEGIN_ARGS*>(pvArgs), reinterpret_cast<BA_ONROLLBACKMSITRANSACTIONBEGIN_RESULTS*>(pvResults));
1586 break;
1587 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONROLLBACKMSITRANSACTIONCOMPLETE:
1588 OnRollbackMsiTransactionCompleteFallback(reinterpret_cast<BA_ONROLLBACKMSITRANSACTIONCOMPLETE_ARGS*>(pvArgs), reinterpret_cast<BA_ONROLLBACKMSITRANSACTIONCOMPLETE_RESULTS*>(pvResults));
1589 break;
1590 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONPAUSEAUTOMATICUPDATESBEGIN:
1591 OnPauseAutomaticUpdatesBeginFallback(reinterpret_cast<BA_ONPAUSEAUTOMATICUPDATESBEGIN_ARGS*>(pvArgs), reinterpret_cast<BA_ONPAUSEAUTOMATICUPDATESBEGIN_RESULTS*>(pvResults));
1592 break;
1593 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONPAUSEAUTOMATICUPDATESCOMPLETE:
1594 OnPauseAutomaticUpdatesCompleteFallback(reinterpret_cast<BA_ONPAUSEAUTOMATICUPDATESCOMPLETE_ARGS*>(pvArgs), reinterpret_cast<BA_ONPAUSEAUTOMATICUPDATESCOMPLETE_RESULTS*>(pvResults));
1595 break;
1596 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONSYSTEMRESTOREPOINTBEGIN:
1597 OnSystemRestorePointBeginFallback(reinterpret_cast<BA_ONSYSTEMRESTOREPOINTBEGIN_ARGS*>(pvArgs), reinterpret_cast<BA_ONSYSTEMRESTOREPOINTBEGIN_RESULTS*>(pvResults));
1598 break;
1599 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONSYSTEMRESTOREPOINTCOMPLETE:
1600 OnSystemRestorePointCompleteFallback(reinterpret_cast<BA_ONSYSTEMRESTOREPOINTCOMPLETE_ARGS*>(pvArgs), reinterpret_cast<BA_ONSYSTEMRESTOREPOINTCOMPLETE_RESULTS*>(pvResults));
1601 break;
1602 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANNEDPACKAGE:
1603 OnPlannedPackageFallback(reinterpret_cast<BA_ONPLANNEDPACKAGE_ARGS*>(pvArgs), reinterpret_cast<BA_ONPLANNEDPACKAGE_RESULTS*>(pvResults));
1604 break;
1605 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEVERIFYPROGRESS:
1606 OnCacheVerifyProgressFallback(reinterpret_cast<BA_ONCACHEVERIFYPROGRESS_ARGS*>(pvArgs), reinterpret_cast<BA_ONCACHEVERIFYPROGRESS_RESULTS*>(pvResults));
1607 break;
1608 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHECONTAINERORPAYLOADVERIFYBEGIN:
1609 OnCacheContainerOrPayloadVerifyBeginFallback(reinterpret_cast<BA_ONCACHECONTAINERORPAYLOADVERIFYBEGIN_ARGS*>(pvArgs), reinterpret_cast<BA_ONCACHECONTAINERORPAYLOADVERIFYBEGIN_RESULTS*>(pvResults));
1610 break;
1611 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHECONTAINERORPAYLOADVERIFYCOMPLETE:
1612 OnCacheContainerOrPayloadVerifyCompleteFallback(reinterpret_cast<BA_ONCACHECONTAINERORPAYLOADVERIFYCOMPLETE_ARGS*>(pvArgs), reinterpret_cast<BA_ONCACHECONTAINERORPAYLOADVERIFYCOMPLETE_RESULTS*>(pvResults));
1613 break;
1614 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHECONTAINERORPAYLOADVERIFYPROGRESS:
1615 OnCacheContainerOrPayloadVerifyProgressFallback(reinterpret_cast<BA_ONCACHECONTAINERORPAYLOADVERIFYPROGRESS_ARGS*>(pvArgs), reinterpret_cast<BA_ONCACHECONTAINERORPAYLOADVERIFYPROGRESS_RESULTS*>(pvResults));
1616 break;
1617 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEPAYLOADEXTRACTBEGIN:
1618 OnCachePayloadExtractBeginFallback(reinterpret_cast<BA_ONCACHEPAYLOADEXTRACTBEGIN_ARGS*>(pvArgs), reinterpret_cast<BA_ONCACHEPAYLOADEXTRACTBEGIN_RESULTS*>(pvResults));
1619 break;
1620 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEPAYLOADEXTRACTCOMPLETE:
1621 OnCachePayloadExtractCompleteFallback(reinterpret_cast<BA_ONCACHEPAYLOADEXTRACTCOMPLETE_ARGS*>(pvArgs), reinterpret_cast<BA_ONCACHEPAYLOADEXTRACTCOMPLETE_RESULTS*>(pvResults));
1622 break;
1623 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEPAYLOADEXTRACTPROGRESS:
1624 OnCachePayloadExtractProgressFallback(reinterpret_cast<BA_ONCACHEPAYLOADEXTRACTPROGRESS_ARGS*>(pvArgs), reinterpret_cast<BA_ONCACHEPAYLOADEXTRACTPROGRESS_RESULTS*>(pvResults));
1625 break;
1626 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANROLLBACKBOUNDARY:
1627 OnPlanRollbackBoundaryFallback(reinterpret_cast<BA_ONPLANROLLBACKBOUNDARY_ARGS*>(pvArgs), reinterpret_cast<BA_ONPLANROLLBACKBOUNDARY_RESULTS*>(pvResults));
1628 break;
1629 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONSETUPDATEBEGIN:
1630 OnSetUpdateBeginFallback(reinterpret_cast<BA_ONSETUPDATEBEGIN_ARGS*>(pvArgs), reinterpret_cast<BA_ONSETUPDATEBEGIN_RESULTS*>(pvResults));
1631 break;
1632 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONSETUPDATECOMPLETE:
1633 OnSetUpdateCompleteFallback(reinterpret_cast<BA_ONSETUPDATECOMPLETE_ARGS*>(pvArgs), reinterpret_cast<BA_ONSETUPDATECOMPLETE_RESULTS*>(pvResults));
1634 break;
1635 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTCOMPATIBLEMSIPACKAGE:
1636 OnDetectCompatibleMsiPackageFallback(reinterpret_cast<BA_ONDETECTCOMPATIBLEMSIPACKAGE_ARGS*>(pvArgs), reinterpret_cast<BA_ONDETECTCOMPATIBLEMSIPACKAGE_RESULTS*>(pvResults));
1637 break;
1638 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANCOMPATIBLEMSIPACKAGEBEGIN:
1639 OnPlanCompatibleMsiPackageBeginFallback(reinterpret_cast<BA_ONPLANCOMPATIBLEMSIPACKAGEBEGIN_ARGS*>(pvArgs), reinterpret_cast<BA_ONPLANCOMPATIBLEMSIPACKAGEBEGIN_RESULTS*>(pvResults));
1640 break;
1641 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANCOMPATIBLEMSIPACKAGECOMPLETE:
1642 OnPlanCompatibleMsiPackageCompleteFallback(reinterpret_cast<BA_ONPLANCOMPATIBLEMSIPACKAGECOMPLETE_ARGS*>(pvArgs), reinterpret_cast<BA_ONPLANCOMPATIBLEMSIPACKAGECOMPLETE_RESULTS*>(pvResults));
1643 break;
1644 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANNEDCOMPATIBLEPACKAGE:
1645 OnPlannedCompatiblePackageFallback(reinterpret_cast<BA_ONPLANNEDCOMPATIBLEPACKAGE_ARGS*>(pvArgs), reinterpret_cast<BA_ONPLANNEDCOMPATIBLEPACKAGE_RESULTS*>(pvResults));
1646 break;
1647 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANRESTORERELATEDBUNDLE:
1648 OnPlanRestoreRelatedBundleFallback(reinterpret_cast<BA_ONPLANRESTORERELATEDBUNDLE_ARGS*>(pvArgs), reinterpret_cast<BA_ONPLANRESTORERELATEDBUNDLE_RESULTS*>(pvResults));
1649 break;
1650 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANRELATEDBUNDLETYPE:
1651 OnPlanRelatedBundleTypeFallback(reinterpret_cast<BA_ONPLANRELATEDBUNDLETYPE_ARGS*>(pvArgs), reinterpret_cast<BA_ONPLANRELATEDBUNDLETYPE_RESULTS*>(pvResults));
1652 break;
1653 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONAPPLYDOWNGRADE:
1654 OnApplyDowngradeFallback(reinterpret_cast<BA_ONAPPLYDOWNGRADE_ARGS*>(pvArgs), reinterpret_cast<BA_ONAPPLYDOWNGRADE_RESULTS*>(pvResults));
1655 break;
1656 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTRELATEDBUNDLEPACKAGE:
1657 OnDetectRelatedBundlePackageFallback(reinterpret_cast<BA_ONDETECTRELATEDBUNDLEPACKAGE_ARGS*>(pvArgs), reinterpret_cast<BA_ONDETECTRELATEDBUNDLEPACKAGE_RESULTS*>(pvResults));
1658 break;
1659 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEPACKAGENONVITALVALIDATIONFAILURE:
1660 OnCachePackageNonVitalValidationFailureFallback(reinterpret_cast<BA_ONCACHEPACKAGENONVITALVALIDATIONFAILURE_ARGS*>(pvArgs), reinterpret_cast<BA_ONCACHEPACKAGENONVITALVALIDATIONFAILURE_RESULTS*>(pvResults));
1661 break;
1662 default:
1663#ifdef DEBUG
1664 BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "WIXSTDBA: Forwarding unknown BA message: %d", message);
1665#endif
1666 m_pfnBAFunctionsProc((BA_FUNCTIONS_MESSAGE)message, pvArgs, pvResults, m_pvBAFunctionsProcContext);
1667 break;
1668 }
1669 }
1670
1671
1672private: // privates
1673 void OnDetectBeginFallback(
1674 __in BA_ONDETECTBEGIN_ARGS* pArgs,
1675 __inout BA_ONDETECTBEGIN_RESULTS* pResults
1676 )
1677 {
1678 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONDETECTBEGIN, pArgs, pResults, m_pvBAFunctionsProcContext);
1679 }
1680
1681 void OnDetectCompleteFallback(
1682 __in BA_ONDETECTCOMPLETE_ARGS* pArgs,
1683 __inout BA_ONDETECTCOMPLETE_RESULTS* pResults
1684 )
1685 {
1686 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONDETECTCOMPLETE, pArgs, pResults, m_pvBAFunctionsProcContext);
1687 }
1688
1689 void OnPlanBeginFallback(
1690 __in BA_ONPLANBEGIN_ARGS* pArgs,
1691 __inout BA_ONPLANBEGIN_RESULTS* pResults
1692 )
1693 {
1694 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONPLANBEGIN, pArgs, pResults, m_pvBAFunctionsProcContext);
1695 }
1696
1697 void OnPlanCompleteFallback(
1698 __in BA_ONPLANCOMPLETE_ARGS* pArgs,
1699 __inout BA_ONPLANCOMPLETE_RESULTS* pResults
1700 )
1701 {
1702 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONPLANCOMPLETE, pArgs, pResults, m_pvBAFunctionsProcContext);
1703 }
1704
1705 void OnShutdownFallback(
1706 __in BA_ONSHUTDOWN_ARGS* pArgs,
1707 __inout BA_ONSHUTDOWN_RESULTS* pResults
1708 )
1709 {
1710 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONSHUTDOWN, pArgs, pResults, m_pvBAFunctionsProcContext);
1711 }
1712
1713 void OnDetectForwardCompatibleBundleFallback(
1714 __in BA_ONDETECTFORWARDCOMPATIBLEBUNDLE_ARGS* pArgs,
1715 __inout BA_ONDETECTFORWARDCOMPATIBLEBUNDLE_RESULTS* pResults
1716 )
1717 {
1718 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONDETECTFORWARDCOMPATIBLEBUNDLE, pArgs, pResults, m_pvBAFunctionsProcContext);
1719 }
1720
1721 void OnDetectUpdateBeginFallback(
1722 __in BA_ONDETECTUPDATEBEGIN_ARGS* pArgs,
1723 __inout BA_ONDETECTUPDATEBEGIN_RESULTS* pResults
1724 )
1725 {
1726 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONDETECTUPDATEBEGIN, pArgs, pResults, m_pvBAFunctionsProcContext);
1727 }
1728
1729 void OnDetectUpdateFallback(
1730 __in BA_ONDETECTUPDATE_ARGS* pArgs,
1731 __inout BA_ONDETECTUPDATE_RESULTS* pResults
1732 )
1733 {
1734 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONDETECTUPDATE, pArgs, pResults, m_pvBAFunctionsProcContext);
1735 }
1736
1737 void OnDetectUpdateCompleteFallback(
1738 __in BA_ONDETECTUPDATECOMPLETE_ARGS* pArgs,
1739 __inout BA_ONDETECTUPDATECOMPLETE_RESULTS* pResults
1740 )
1741 {
1742 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONDETECTUPDATECOMPLETE, pArgs, pResults, m_pvBAFunctionsProcContext);
1743 }
1744
1745 void OnDetectRelatedBundleFallback(
1746 __in BA_ONDETECTRELATEDBUNDLE_ARGS* pArgs,
1747 __inout BA_ONDETECTRELATEDBUNDLE_RESULTS* pResults
1748 )
1749 {
1750 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONDETECTRELATEDBUNDLE, pArgs, pResults, m_pvBAFunctionsProcContext);
1751 }
1752
1753 void OnDetectPackageBeginFallback(
1754 __in BA_ONDETECTPACKAGEBEGIN_ARGS* pArgs,
1755 __inout BA_ONDETECTPACKAGEBEGIN_RESULTS* pResults
1756 )
1757 {
1758 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONDETECTPACKAGEBEGIN, pArgs, pResults, m_pvBAFunctionsProcContext);
1759 }
1760
1761 void OnDetectRelatedMsiPackageFallback(
1762 __in BA_ONDETECTRELATEDMSIPACKAGE_ARGS* pArgs,
1763 __inout BA_ONDETECTRELATEDMSIPACKAGE_RESULTS* pResults
1764 )
1765 {
1766 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONDETECTRELATEDMSIPACKAGE, pArgs, pResults, m_pvBAFunctionsProcContext);
1767 }
1768
1769 void OnDetectPatchTargetFallback(
1770 __in BA_ONDETECTPATCHTARGET_ARGS* pArgs,
1771 __inout BA_ONDETECTPATCHTARGET_RESULTS* pResults
1772 )
1773 {
1774 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONDETECTPATCHTARGET, pArgs, pResults, m_pvBAFunctionsProcContext);
1775 }
1776
1777 void OnDetectMsiFeatureFallback(
1778 __in BA_ONDETECTMSIFEATURE_ARGS* pArgs,
1779 __inout BA_ONDETECTMSIFEATURE_RESULTS* pResults
1780 )
1781 {
1782 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONDETECTMSIFEATURE, pArgs, pResults, m_pvBAFunctionsProcContext);
1783 }
1784
1785 void OnDetectPackageCompleteFallback(
1786 __in BA_ONDETECTPACKAGECOMPLETE_ARGS* pArgs,
1787 __inout BA_ONDETECTPACKAGECOMPLETE_RESULTS* pResults
1788 )
1789 {
1790 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONDETECTPACKAGECOMPLETE, pArgs, pResults, m_pvBAFunctionsProcContext);
1791 }
1792
1793 void OnPlanRelatedBundleFallback(
1794 __in BA_ONPLANRELATEDBUNDLE_ARGS* pArgs,
1795 __inout BA_ONPLANRELATEDBUNDLE_RESULTS* pResults
1796 )
1797 {
1798 BOOTSTRAPPER_REQUEST_STATE requestedState = pResults->requestedState;
1799 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONPLANRELATEDBUNDLE, pArgs, pResults, m_pvBAFunctionsProcContext);
1800 BalLogId(BOOTSTRAPPER_LOG_LEVEL_STANDARD, MSG_WIXSTDBA_PLANNED_RELATED_BUNDLE, m_hModule, pArgs->wzBundleId, LoggingRequestStateToString(requestedState), LoggingRequestStateToString(pResults->requestedState));
1801 }
1802
1803 void OnPlanRelatedBundleTypeFallback(
1804 __in BA_ONPLANRELATEDBUNDLETYPE_ARGS* pArgs,
1805 __inout BA_ONPLANRELATEDBUNDLETYPE_RESULTS* pResults
1806 )
1807 {
1808 BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE requestedType = pResults->requestedType;
1809 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONPLANRELATEDBUNDLETYPE, pArgs, pResults, m_pvBAFunctionsProcContext);
1810 BalLogId(BOOTSTRAPPER_LOG_LEVEL_STANDARD, MSG_WIXSTDBA_PLANNED_RELATED_BUNDLE_TYPE, m_hModule, pArgs->wzBundleId, LoggingPlanRelationTypeToString(requestedType), LoggingPlanRelationTypeToString(pResults->requestedType));
1811 }
1812
1813 void OnPlanPackageBeginFallback(
1814 __in BA_ONPLANPACKAGEBEGIN_ARGS* pArgs,
1815 __inout BA_ONPLANPACKAGEBEGIN_RESULTS* pResults
1816 )
1817 {
1818 BOOTSTRAPPER_REQUEST_STATE requestedState = pResults->requestedState;
1819 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONPLANPACKAGEBEGIN, pArgs, pResults, m_pvBAFunctionsProcContext);
1820 BalLogId(BOOTSTRAPPER_LOG_LEVEL_STANDARD, MSG_WIXSTDBA_PLANNED_PACKAGE, m_hModule, pArgs->wzPackageId, LoggingRequestStateToString(requestedState), LoggingRequestStateToString(pResults->requestedState));
1821 }
1822
1823 void OnPlanPatchTargetFallback(
1824 __in BA_ONPLANPATCHTARGET_ARGS* pArgs,
1825 __inout BA_ONPLANPATCHTARGET_RESULTS* pResults
1826 )
1827 {
1828 BOOTSTRAPPER_REQUEST_STATE requestedState = pResults->requestedState;
1829 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONPLANPATCHTARGET, pArgs, pResults, m_pvBAFunctionsProcContext);
1830 BalLogId(BOOTSTRAPPER_LOG_LEVEL_STANDARD, MSG_WIXSTDBA_PLANNED_TARGET_MSI_PACKAGE, m_hModule, pArgs->wzPackageId, pArgs->wzProductCode, LoggingRequestStateToString(requestedState), LoggingRequestStateToString(pResults->requestedState));
1831 }
1832
1833 void OnPlanMsiFeatureFallback(
1834 __in BA_ONPLANMSIFEATURE_ARGS* pArgs,
1835 __inout BA_ONPLANMSIFEATURE_RESULTS* pResults
1836 )
1837 {
1838 BOOTSTRAPPER_FEATURE_STATE requestedState = pResults->requestedState;
1839 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONPLANMSIFEATURE, pArgs, pResults, m_pvBAFunctionsProcContext);
1840 BalLogId(BOOTSTRAPPER_LOG_LEVEL_STANDARD, MSG_WIXSTDBA_PLANNED_MSI_FEATURE, m_hModule, pArgs->wzPackageId, pArgs->wzFeatureId, LoggingMsiFeatureStateToString(requestedState), LoggingMsiFeatureStateToString(pResults->requestedState));
1841 }
1842
1843 void OnPlanPackageCompleteFallback(
1844 __in BA_ONPLANPACKAGECOMPLETE_ARGS* pArgs,
1845 __inout BA_ONPLANPACKAGECOMPLETE_RESULTS* pResults
1846 )
1847 {
1848 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONPLANPACKAGECOMPLETE, pArgs, pResults, m_pvBAFunctionsProcContext);
1849 }
1850
1851 void OnPlannedCompatiblePackageFallback(
1852 __in BA_ONPLANNEDCOMPATIBLEPACKAGE_ARGS* pArgs,
1853 __inout BA_ONPLANNEDCOMPATIBLEPACKAGE_RESULTS* pResults
1854 )
1855 {
1856 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONPLANNEDCOMPATIBLEPACKAGE, pArgs, pResults, m_pvBAFunctionsProcContext);
1857 }
1858
1859 void OnPlannedPackageFallback(
1860 __in BA_ONPLANNEDPACKAGE_ARGS* pArgs,
1861 __inout BA_ONPLANNEDPACKAGE_RESULTS* pResults
1862 )
1863 {
1864 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONPLANNEDPACKAGE, pArgs, pResults, m_pvBAFunctionsProcContext);
1865 }
1866
1867 void OnApplyBeginFallback(
1868 __in BA_ONAPPLYBEGIN_ARGS* pArgs,
1869 __inout BA_ONAPPLYBEGIN_RESULTS* pResults
1870 )
1871 {
1872 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONAPPLYBEGIN, pArgs, pResults, m_pvBAFunctionsProcContext);
1873 }
1874
1875 void OnElevateBeginFallback(
1876 __in BA_ONELEVATEBEGIN_ARGS* pArgs,
1877 __inout BA_ONELEVATEBEGIN_RESULTS* pResults
1878 )
1879 {
1880 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONELEVATEBEGIN, pArgs, pResults, m_pvBAFunctionsProcContext);
1881 }
1882
1883 void OnElevateCompleteFallback(
1884 __in BA_ONELEVATECOMPLETE_ARGS* pArgs,
1885 __inout BA_ONELEVATECOMPLETE_RESULTS* pResults
1886 )
1887 {
1888 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONELEVATECOMPLETE, pArgs, pResults, m_pvBAFunctionsProcContext);
1889 }
1890
1891 void OnProgressFallback(
1892 __in BA_ONPROGRESS_ARGS* pArgs,
1893 __inout BA_ONPROGRESS_RESULTS* pResults
1894 )
1895 {
1896 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONPROGRESS, pArgs, pResults, m_pvBAFunctionsProcContext);
1897 }
1898
1899 void OnErrorFallback(
1900 __in BA_ONERROR_ARGS* pArgs,
1901 __inout BA_ONERROR_RESULTS* pResults
1902 )
1903 {
1904 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONERROR, pArgs, pResults, m_pvBAFunctionsProcContext);
1905 }
1906
1907 void OnRegisterBeginFallback(
1908 __in BA_ONREGISTERBEGIN_ARGS* pArgs,
1909 __inout BA_ONREGISTERBEGIN_RESULTS* pResults
1910 )
1911 {
1912 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONREGISTERBEGIN, pArgs, pResults, m_pvBAFunctionsProcContext);
1913 }
1914
1915 void OnRegisterCompleteFallback(
1916 __in BA_ONREGISTERCOMPLETE_ARGS* pArgs,
1917 __inout BA_ONREGISTERCOMPLETE_RESULTS* pResults
1918 )
1919 {
1920 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONREGISTERCOMPLETE, pArgs, pResults, m_pvBAFunctionsProcContext);
1921 }
1922
1923 void OnCacheBeginFallback(
1924 __in BA_ONCACHEBEGIN_ARGS* pArgs,
1925 __inout BA_ONCACHEBEGIN_RESULTS* pResults
1926 )
1927 {
1928 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONCACHEBEGIN, pArgs, pResults, m_pvBAFunctionsProcContext);
1929 }
1930
1931 void OnCachePackageBeginFallback(
1932 __in BA_ONCACHEPACKAGEBEGIN_ARGS* pArgs,
1933 __inout BA_ONCACHEPACKAGEBEGIN_RESULTS* pResults
1934 )
1935 {
1936 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONCACHEPACKAGEBEGIN, pArgs, pResults, m_pvBAFunctionsProcContext);
1937 }
1938
1939 void OnCacheAcquireBeginFallback(
1940 __in BA_ONCACHEACQUIREBEGIN_ARGS* pArgs,
1941 __inout BA_ONCACHEACQUIREBEGIN_RESULTS* pResults
1942 )
1943 {
1944 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONCACHEACQUIREBEGIN, pArgs, pResults, m_pvBAFunctionsProcContext);
1945 }
1946
1947 void OnCacheAcquireProgressFallback(
1948 __in BA_ONCACHEACQUIREPROGRESS_ARGS* pArgs,
1949 __inout BA_ONCACHEACQUIREPROGRESS_RESULTS* pResults
1950 )
1951 {
1952 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONCACHEACQUIREPROGRESS, pArgs, pResults, m_pvBAFunctionsProcContext);
1953 }
1954
1955 void OnCacheAcquireResolvingFallback(
1956 __in BA_ONCACHEACQUIRERESOLVING_ARGS* pArgs,
1957 __inout BA_ONCACHEACQUIRERESOLVING_RESULTS* pResults
1958 )
1959 {
1960 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONCACHEACQUIRERESOLVING, pArgs, pResults, m_pvBAFunctionsProcContext);
1961 }
1962
1963 void OnCacheAcquireCompleteFallback(
1964 __in BA_ONCACHEACQUIRECOMPLETE_ARGS* pArgs,
1965 __inout BA_ONCACHEACQUIRECOMPLETE_RESULTS* pResults
1966 )
1967 {
1968 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONCACHEACQUIRECOMPLETE, pArgs, pResults, m_pvBAFunctionsProcContext);
1969 }
1970
1971 void OnCacheVerifyBeginFallback(
1972 __in BA_ONCACHEVERIFYBEGIN_ARGS* pArgs,
1973 __inout BA_ONCACHEVERIFYBEGIN_RESULTS* pResults
1974 )
1975 {
1976 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONCACHEVERIFYBEGIN, pArgs, pResults, m_pvBAFunctionsProcContext);
1977 }
1978
1979 void OnCacheVerifyCompleteFallback(
1980 __in BA_ONCACHEVERIFYCOMPLETE_ARGS* pArgs,
1981 __inout BA_ONCACHEVERIFYCOMPLETE_RESULTS* pResults
1982 )
1983 {
1984 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONCACHEVERIFYCOMPLETE, pArgs, pResults, m_pvBAFunctionsProcContext);
1985 }
1986
1987 void OnCachePackageCompleteFallback(
1988 __in BA_ONCACHEPACKAGECOMPLETE_ARGS* pArgs,
1989 __inout BA_ONCACHEPACKAGECOMPLETE_RESULTS* pResults
1990 )
1991 {
1992 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONCACHEPACKAGECOMPLETE, pArgs, pResults, m_pvBAFunctionsProcContext);
1993 }
1994
1995 void OnCacheCompleteFallback(
1996 __in BA_ONCACHECOMPLETE_ARGS* pArgs,
1997 __inout BA_ONCACHECOMPLETE_RESULTS* pResults
1998 )
1999 {
2000 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONCACHECOMPLETE, pArgs, pResults, m_pvBAFunctionsProcContext);
2001 }
2002
2003 void OnExecuteBeginFallback(
2004 __in BA_ONEXECUTEBEGIN_ARGS* pArgs,
2005 __inout BA_ONEXECUTEBEGIN_RESULTS* pResults
2006 )
2007 {
2008 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONEXECUTEBEGIN, pArgs, pResults, m_pvBAFunctionsProcContext);
2009 }
2010
2011 void OnExecutePackageBeginFallback(
2012 __in BA_ONEXECUTEPACKAGEBEGIN_ARGS* pArgs,
2013 __inout BA_ONEXECUTEPACKAGEBEGIN_RESULTS* pResults
2014 )
2015 {
2016 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONEXECUTEPACKAGEBEGIN, pArgs, pResults, m_pvBAFunctionsProcContext);
2017 }
2018
2019 void OnExecutePatchTargetFallback(
2020 __in BA_ONEXECUTEPATCHTARGET_ARGS* pArgs,
2021 __inout BA_ONEXECUTEPATCHTARGET_RESULTS* pResults
2022 )
2023 {
2024 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONEXECUTEPATCHTARGET, pArgs, pResults, m_pvBAFunctionsProcContext);
2025 }
2026
2027 void OnExecuteProgressFallback(
2028 __in BA_ONEXECUTEPROGRESS_ARGS* pArgs,
2029 __inout BA_ONEXECUTEPROGRESS_RESULTS* pResults
2030 )
2031 {
2032 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONEXECUTEPROGRESS, pArgs, pResults, m_pvBAFunctionsProcContext);
2033 }
2034
2035 void OnExecuteMsiMessageFallback(
2036 __in BA_ONEXECUTEMSIMESSAGE_ARGS* pArgs,
2037 __inout BA_ONEXECUTEMSIMESSAGE_RESULTS* pResults
2038 )
2039 {
2040 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONEXECUTEMSIMESSAGE, pArgs, pResults, m_pvBAFunctionsProcContext);
2041 }
2042
2043 void OnExecuteFilesInUseFallback(
2044 __in BA_ONEXECUTEFILESINUSE_ARGS* pArgs,
2045 __inout BA_ONEXECUTEFILESINUSE_RESULTS* pResults
2046 )
2047 {
2048 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONEXECUTEFILESINUSE, pArgs, pResults, m_pvBAFunctionsProcContext);
2049 }
2050
2051 void OnExecutePackageCompleteFallback(
2052 __in BA_ONEXECUTEPACKAGECOMPLETE_ARGS* pArgs,
2053 __inout BA_ONEXECUTEPACKAGECOMPLETE_RESULTS* pResults
2054 )
2055 {
2056 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONEXECUTEPACKAGECOMPLETE, pArgs, pResults, m_pvBAFunctionsProcContext);
2057 }
2058
2059 void OnExecuteCompleteFallback(
2060 __in BA_ONEXECUTECOMPLETE_ARGS* pArgs,
2061 __inout BA_ONEXECUTECOMPLETE_RESULTS* pResults
2062 )
2063 {
2064 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONEXECUTECOMPLETE, pArgs, pResults, m_pvBAFunctionsProcContext);
2065 }
2066
2067 void OnUnregisterBeginFallback(
2068 __in BA_ONUNREGISTERBEGIN_ARGS* pArgs,
2069 __inout BA_ONUNREGISTERBEGIN_RESULTS* pResults
2070 )
2071 {
2072 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONUNREGISTERBEGIN, pArgs, pResults, m_pvBAFunctionsProcContext);
2073 }
2074
2075 void OnUnregisterCompleteFallback(
2076 __in BA_ONUNREGISTERCOMPLETE_ARGS* pArgs,
2077 __inout BA_ONUNREGISTERCOMPLETE_RESULTS* pResults
2078 )
2079 {
2080 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONUNREGISTERCOMPLETE, pArgs, pResults, m_pvBAFunctionsProcContext);
2081 }
2082
2083 void OnApplyCompleteFallback(
2084 __in BA_ONAPPLYCOMPLETE_ARGS* pArgs,
2085 __inout BA_ONAPPLYCOMPLETE_RESULTS* pResults
2086 )
2087 {
2088 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONAPPLYCOMPLETE, pArgs, pResults, m_pvBAFunctionsProcContext);
2089 }
2090
2091 void OnLaunchApprovedExeBeginFallback(
2092 __in BA_ONLAUNCHAPPROVEDEXEBEGIN_ARGS* pArgs,
2093 __inout BA_ONLAUNCHAPPROVEDEXEBEGIN_RESULTS* pResults
2094 )
2095 {
2096 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONLAUNCHAPPROVEDEXEBEGIN, pArgs, pResults, m_pvBAFunctionsProcContext);
2097 }
2098
2099 void OnLaunchApprovedExeCompleteFallback(
2100 __in BA_ONLAUNCHAPPROVEDEXECOMPLETE_ARGS* pArgs,
2101 __inout BA_ONLAUNCHAPPROVEDEXECOMPLETE_RESULTS* pResults
2102 )
2103 {
2104 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONLAUNCHAPPROVEDEXECOMPLETE, pArgs, pResults, m_pvBAFunctionsProcContext);
2105 }
2106
2107 void OnPlanMsiPackageFallback(
2108 __in BA_ONPLANMSIPACKAGE_ARGS* pArgs,
2109 __inout BA_ONPLANMSIPACKAGE_RESULTS* pResults
2110 )
2111 {
2112 BURN_MSI_PROPERTY actionMsiProperty = pResults->actionMsiProperty;
2113 INSTALLUILEVEL uiLevel = pResults->uiLevel;
2114 BOOL fDisableExternalUiHandler = pResults->fDisableExternalUiHandler;
2115 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONPLANMSIPACKAGE, pArgs, pResults, m_pvBAFunctionsProcContext);
2116 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");
2117 }
2118
2119 void OnBeginMsiTransactionBeginFallback(
2120 __in BA_ONBEGINMSITRANSACTIONBEGIN_ARGS* pArgs,
2121 __inout BA_ONBEGINMSITRANSACTIONBEGIN_RESULTS* pResults
2122 )
2123 {
2124 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONBEGINMSITRANSACTIONBEGIN, pArgs, pResults, m_pvBAFunctionsProcContext);
2125 }
2126
2127 void OnBeginMsiTransactionCompleteFallback(
2128 __in BA_ONBEGINMSITRANSACTIONCOMPLETE_ARGS* pArgs,
2129 __inout BA_ONBEGINMSITRANSACTIONCOMPLETE_RESULTS* pResults
2130 )
2131 {
2132 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONBEGINMSITRANSACTIONCOMPLETE, pArgs, pResults, m_pvBAFunctionsProcContext);
2133 }
2134
2135 void OnCommitMsiTransactionBeginFallback(
2136 __in BA_ONCOMMITMSITRANSACTIONBEGIN_ARGS* pArgs,
2137 __inout BA_ONCOMMITMSITRANSACTIONBEGIN_RESULTS* pResults
2138 )
2139 {
2140 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONCOMMITMSITRANSACTIONBEGIN, pArgs, pResults, m_pvBAFunctionsProcContext);
2141 }
2142
2143 void OnCommitMsiTransactionCompleteFallback(
2144 __in BA_ONCOMMITMSITRANSACTIONCOMPLETE_ARGS* pArgs,
2145 __inout BA_ONCOMMITMSITRANSACTIONCOMPLETE_RESULTS* pResults
2146 )
2147 {
2148 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONCOMMITMSITRANSACTIONCOMPLETE, pArgs, pResults, m_pvBAFunctionsProcContext);
2149 }
2150
2151 void OnRollbackMsiTransactionBeginFallback(
2152 __in BA_ONROLLBACKMSITRANSACTIONBEGIN_ARGS* pArgs,
2153 __inout BA_ONROLLBACKMSITRANSACTIONBEGIN_RESULTS* pResults
2154 )
2155 {
2156 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONROLLBACKMSITRANSACTIONBEGIN, pArgs, pResults, m_pvBAFunctionsProcContext);
2157 }
2158
2159 void OnRollbackMsiTransactionCompleteFallback(
2160 __in BA_ONROLLBACKMSITRANSACTIONCOMPLETE_ARGS* pArgs,
2161 __inout BA_ONROLLBACKMSITRANSACTIONCOMPLETE_RESULTS* pResults
2162 )
2163 {
2164 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONROLLBACKMSITRANSACTIONCOMPLETE, pArgs, pResults, m_pvBAFunctionsProcContext);
2165 }
2166
2167 void OnPauseAutomaticUpdatesBeginFallback(
2168 __in BA_ONPAUSEAUTOMATICUPDATESBEGIN_ARGS* pArgs,
2169 __inout BA_ONPAUSEAUTOMATICUPDATESBEGIN_RESULTS* pResults
2170 )
2171 {
2172 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONPAUSEAUTOMATICUPDATESBEGIN, pArgs, pResults, m_pvBAFunctionsProcContext);
2173 }
2174
2175 void OnPauseAutomaticUpdatesCompleteFallback(
2176 __in BA_ONPAUSEAUTOMATICUPDATESCOMPLETE_ARGS* pArgs,
2177 __inout BA_ONPAUSEAUTOMATICUPDATESCOMPLETE_RESULTS* pResults
2178 )
2179 {
2180 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONPAUSEAUTOMATICUPDATESCOMPLETE, pArgs, pResults, m_pvBAFunctionsProcContext);
2181 }
2182
2183 void OnSystemRestorePointBeginFallback(
2184 __in BA_ONSYSTEMRESTOREPOINTBEGIN_ARGS* pArgs,
2185 __inout BA_ONSYSTEMRESTOREPOINTBEGIN_RESULTS* pResults
2186 )
2187 {
2188 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONSYSTEMRESTOREPOINTBEGIN, pArgs, pResults, m_pvBAFunctionsProcContext);
2189 }
2190
2191 void OnSystemRestorePointCompleteFallback(
2192 __in BA_ONSYSTEMRESTOREPOINTCOMPLETE_ARGS* pArgs,
2193 __inout BA_ONSYSTEMRESTOREPOINTCOMPLETE_RESULTS* pResults
2194 )
2195 {
2196 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONSYSTEMRESTOREPOINTCOMPLETE, pArgs, pResults, m_pvBAFunctionsProcContext);
2197 }
2198
2199 void OnPlanForwardCompatibleBundleFallback(
2200 __in BA_ONPLANFORWARDCOMPATIBLEBUNDLE_ARGS* pArgs,
2201 __inout BA_ONPLANFORWARDCOMPATIBLEBUNDLE_RESULTS* pResults
2202 )
2203 {
2204 BOOL fIgnoreBundle = pResults->fIgnoreBundle;
2205 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONPLANFORWARDCOMPATIBLEBUNDLE, pArgs, pResults, m_pvBAFunctionsProcContext);
2206 BalLogId(BOOTSTRAPPER_LOG_LEVEL_STANDARD, MSG_WIXSTDBA_PLANNED_FORWARD_COMPATIBLE_BUNDLE, m_hModule, pArgs->wzBundleId, fIgnoreBundle ? "ignore" : "enable", pResults->fIgnoreBundle ? "ignore" : "enable");
2207 }
2208
2209 void OnCacheVerifyProgressFallback(
2210 __in BA_ONCACHEVERIFYPROGRESS_ARGS* pArgs,
2211 __inout BA_ONCACHEVERIFYPROGRESS_RESULTS* pResults
2212 )
2213 {
2214 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONCACHEVERIFYPROGRESS, pArgs, pResults, m_pvBAFunctionsProcContext);
2215 }
2216
2217 void OnCacheContainerOrPayloadVerifyBeginFallback(
2218 __in BA_ONCACHECONTAINERORPAYLOADVERIFYBEGIN_ARGS* pArgs,
2219 __inout BA_ONCACHECONTAINERORPAYLOADVERIFYBEGIN_RESULTS* pResults
2220 )
2221 {
2222 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONCACHECONTAINERORPAYLOADVERIFYBEGIN, pArgs, pResults, m_pvBAFunctionsProcContext);
2223 }
2224
2225 void OnCacheContainerOrPayloadVerifyCompleteFallback(
2226 __in BA_ONCACHECONTAINERORPAYLOADVERIFYCOMPLETE_ARGS* pArgs,
2227 __inout BA_ONCACHECONTAINERORPAYLOADVERIFYCOMPLETE_RESULTS* pResults
2228 )
2229 {
2230 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONCACHECONTAINERORPAYLOADVERIFYCOMPLETE, pArgs, pResults, m_pvBAFunctionsProcContext);
2231 }
2232
2233 void OnCacheContainerOrPayloadVerifyProgressFallback(
2234 __in BA_ONCACHECONTAINERORPAYLOADVERIFYPROGRESS_ARGS* pArgs,
2235 __inout BA_ONCACHECONTAINERORPAYLOADVERIFYPROGRESS_RESULTS* pResults
2236 )
2237 {
2238 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONCACHECONTAINERORPAYLOADVERIFYPROGRESS, pArgs, pResults, m_pvBAFunctionsProcContext);
2239 }
2240
2241 void OnCachePayloadExtractBeginFallback(
2242 __in BA_ONCACHEPAYLOADEXTRACTBEGIN_ARGS* pArgs,
2243 __inout BA_ONCACHEPAYLOADEXTRACTBEGIN_RESULTS* pResults
2244 )
2245 {
2246 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONCACHEPAYLOADEXTRACTBEGIN, pArgs, pResults, m_pvBAFunctionsProcContext);
2247 }
2248
2249 void OnCachePayloadExtractCompleteFallback(
2250 __in BA_ONCACHEPAYLOADEXTRACTCOMPLETE_ARGS* pArgs,
2251 __inout BA_ONCACHEPAYLOADEXTRACTCOMPLETE_RESULTS* pResults
2252 )
2253 {
2254 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONCACHEPAYLOADEXTRACTCOMPLETE, pArgs, pResults, m_pvBAFunctionsProcContext);
2255 }
2256
2257 void OnCachePayloadExtractProgressFallback(
2258 __in BA_ONCACHEPAYLOADEXTRACTPROGRESS_ARGS* pArgs,
2259 __inout BA_ONCACHEPAYLOADEXTRACTPROGRESS_RESULTS* pResults
2260 )
2261 {
2262 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONCACHEPAYLOADEXTRACTPROGRESS, pArgs, pResults, m_pvBAFunctionsProcContext);
2263 }
2264
2265 void OnPlanRollbackBoundaryFallback(
2266 __in BA_ONPLANROLLBACKBOUNDARY_ARGS* pArgs,
2267 __inout BA_ONPLANROLLBACKBOUNDARY_RESULTS* pResults
2268 )
2269 {
2270 BOOL fTransaction = pResults->fTransaction;
2271 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONPLANROLLBACKBOUNDARY, pArgs, pResults, m_pvBAFunctionsProcContext);
2272 BalLogId(BOOTSTRAPPER_LOG_LEVEL_STANDARD, MSG_WIXSTDBA_PLANNED_ROLLBACK_BOUNDARY, m_hModule, pArgs->wzRollbackBoundaryId, LoggingBoolToString(fTransaction), LoggingBoolToString(pResults->fTransaction));
2273 }
2274
2275 void OnSetUpdateBeginFallback(
2276 __in BA_ONSETUPDATEBEGIN_ARGS* pArgs,
2277 __inout BA_ONSETUPDATEBEGIN_RESULTS* pResults
2278 )
2279 {
2280 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONSETUPDATEBEGIN, pArgs, pResults, m_pvBAFunctionsProcContext);
2281 }
2282
2283 void OnSetUpdateCompleteFallback(
2284 __in BA_ONSETUPDATECOMPLETE_ARGS* pArgs,
2285 __inout BA_ONSETUPDATECOMPLETE_RESULTS* pResults
2286 )
2287 {
2288 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONSETUPDATECOMPLETE, pArgs, pResults, m_pvBAFunctionsProcContext);
2289 }
2290
2291 void OnDetectCompatibleMsiPackageFallback(
2292 __in BA_ONDETECTCOMPATIBLEMSIPACKAGE_ARGS* pArgs,
2293 __inout BA_ONDETECTCOMPATIBLEMSIPACKAGE_RESULTS* pResults
2294 )
2295 {
2296 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONDETECTCOMPATIBLEMSIPACKAGE, pArgs, pResults, m_pvBAFunctionsProcContext);
2297 }
2298
2299 void OnPlanCompatibleMsiPackageBeginFallback(
2300 __in BA_ONPLANCOMPATIBLEMSIPACKAGEBEGIN_ARGS* pArgs,
2301 __inout BA_ONPLANCOMPATIBLEMSIPACKAGEBEGIN_RESULTS* pResults
2302 )
2303 {
2304 BOOL fRequestRemove = pResults->fRequestRemove;
2305 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONPLANCOMPATIBLEMSIPACKAGEBEGIN, pArgs, pResults, m_pvBAFunctionsProcContext);
2306 BalLogId(BOOTSTRAPPER_LOG_LEVEL_STANDARD, MSG_WIXSTDBA_PLANNED_COMPATIBLE_MSI_PACKAGE, m_hModule, pArgs->wzPackageId, pArgs->wzCompatiblePackageId, LoggingBoolToString(fRequestRemove), LoggingBoolToString(pResults->fRequestRemove));
2307 }
2308
2309 void OnPlanCompatibleMsiPackageCompleteFallback(
2310 __in BA_ONPLANCOMPATIBLEMSIPACKAGECOMPLETE_ARGS* pArgs,
2311 __inout BA_ONPLANCOMPATIBLEMSIPACKAGECOMPLETE_RESULTS* pResults
2312 )
2313 {
2314 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONPLANCOMPATIBLEMSIPACKAGECOMPLETE, pArgs, pResults, m_pvBAFunctionsProcContext);
2315 }
2316
2317 void OnPlanRestoreRelatedBundleFallback(
2318 __in BA_ONPLANRESTORERELATEDBUNDLE_ARGS* pArgs,
2319 __inout BA_ONPLANRESTORERELATEDBUNDLE_RESULTS* pResults
2320 )
2321 {
2322 BOOTSTRAPPER_REQUEST_STATE requestedState = pResults->requestedState;
2323 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONPLANRESTORERELATEDBUNDLE, pArgs, pResults, m_pvBAFunctionsProcContext);
2324 BalLogId(BOOTSTRAPPER_LOG_LEVEL_STANDARD, MSG_WIXSTDBA_PLANNED_RESTORE_RELATED_BUNDLE, m_hModule, pArgs->wzBundleId, LoggingRequestStateToString(requestedState), LoggingRequestStateToString(pResults->requestedState));
2325 }
2326
2327 void OnApplyDowngradeFallback(
2328 __in BA_ONAPPLYDOWNGRADE_ARGS* pArgs,
2329 __inout BA_ONAPPLYDOWNGRADE_RESULTS* pResults
2330 )
2331 {
2332 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONAPPLYDOWNGRADE, pArgs, pResults, m_pvBAFunctionsProcContext);
2333 }
2334
2335 void OnExecuteProcessCancelFallback(
2336 __in BA_ONEXECUTEPROCESSCANCEL_ARGS* pArgs,
2337 __inout BA_ONEXECUTEPROCESSCANCEL_RESULTS* pResults
2338 )
2339 {
2340 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONEXECUTEPROCESSCANCEL, pArgs, pResults, m_pvBAFunctionsProcContext);
2341 }
2342
2343 void OnDetectRelatedBundlePackageFallback(
2344 __in BA_ONDETECTRELATEDBUNDLEPACKAGE_ARGS* pArgs,
2345 __inout BA_ONDETECTRELATEDBUNDLEPACKAGE_RESULTS* pResults
2346 )
2347 {
2348 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONDETECTRELATEDBUNDLEPACKAGE, pArgs, pResults, m_pvBAFunctionsProcContext);
2349 }
2350
2351 void OnCachePackageNonVitalValidationFailureFallback(
2352 __in BA_ONCACHEPACKAGENONVITALVALIDATIONFAILURE_ARGS* pArgs,
2353 __inout BA_ONCACHEPACKAGENONVITALVALIDATIONFAILURE_RESULTS* pResults
2354 )
2355 {
2356 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONCACHEPACKAGENONVITALVALIDATIONFAILURE, pArgs, pResults, m_pvBAFunctionsProcContext);
2357 }
2358
2359
2360 HRESULT ShowMsiFilesInUse(
2361 __in DWORD cFiles,
2362 __in_ecount_z(cFiles) LPCWSTR* rgwzFiles,
2363 __in BOOTSTRAPPER_FILES_IN_USE_TYPE source,
2364 __inout int* pResult
2365 )
2366 {
2367 HRESULT hr = S_OK;
2368 LPWSTR sczFilesInUse = NULL;
2369 DWORD_PTR cchLen = 0;
2370 int nResult = IDERROR;
2371
2372 // If the user has chosen to ignore on a previously displayed "files in use" page,
2373 // we will return the same result for other cases. No need to display the page again.
2374 if (IDIGNORE == m_nLastMsiFilesInUseResult)
2375 {
2376 nResult = m_nLastMsiFilesInUseResult;
2377 }
2378 else if (BOOTSTRAPPER_DISPLAY_FULL == m_command.display) // Only show files in use when using full display mode.
2379 {
2380 // See https://docs.microsoft.com/en-us/windows/win32/msi/sending-messages-to-windows-installer-using-msiprocessmessage for details.
2381 for (DWORD i = 1; i < cFiles; i += 2)
2382 {
2383 hr = ::StringCchLengthW(rgwzFiles[i], STRSAFE_MAX_CCH, reinterpret_cast<UINT_PTR*>(&cchLen));
2384 BalExitOnFailure(hr, "Failed to calculate length of string.");
2385
2386 if (cchLen)
2387 {
2388 hr = StrAllocConcatFormatted(&sczFilesInUse, L"%ls\r\n", rgwzFiles[i]);
2389 BalExitOnFailure(hr, "Failed to concat files in use.");
2390 }
2391 }
2392
2393 // Show applications using the files.
2394 if (BOOTSTRAPPER_FILES_IN_USE_TYPE_MSI_RM == source)
2395 {
2396 hr = ShowRestartManagerMsiFilesInUseDialog(sczFilesInUse, &nResult);
2397 ExitOnFailure(hr, "Failed to show RM files-in-use dialog.");
2398 }
2399 else
2400 {
2401 hr = ShowStandardMsiFilesInUseDialog(sczFilesInUse, &nResult);
2402 ExitOnFailure(hr, "Failed to show files-in-use dialog.");
2403 }
2404 }
2405 else
2406 {
2407 // Silent UI level installations always shut down applications and services,
2408 // and on Windows Vista and later, use Restart Manager unless disabled.
2409 nResult = IDOK;
2410 }
2411
2412 LExit:
2413 ReleaseStr(sczFilesInUse);
2414
2415 // Remember the answer from the user.
2416 m_nLastMsiFilesInUseResult = FAILED(hr) ? IDERROR : nResult;
2417 *pResult = m_nLastMsiFilesInUseResult;
2418
2419 return hr;
2420 }
2421
2422
2423 int ShowRestartManagerMsiFilesInUseDialog(
2424 __in_z_opt LPCWSTR sczFilesInUse,
2425 __out int* pnResult
2426 )
2427 {
2428 HRESULT hr = S_OK;
2429 TASKDIALOGCONFIG config = { };
2430 LPWSTR sczTitle = NULL;
2431 LPWSTR sczLabel = NULL;
2432 LPWSTR sczCloseRadioButton = NULL;
2433 LPWSTR sczDontCloseRadioButton = NULL;
2434 int nButton = 0;
2435 int nRadioButton = 0;
2436
2437 hr = BalFormatString(m_pFilesInUseTitleLoc->wzText, &sczTitle);
2438 BalExitOnFailure(hr, "Failed to format FilesInUseTitle loc string.");
2439
2440 hr = BalFormatString(m_pFilesInUseLabelLoc->wzText, &sczLabel);
2441 BalExitOnFailure(hr, "Failed to format FilesInUseLabel loc string.");
2442
2443 hr = BalFormatString(m_pFilesInUseCloseRadioButtonLoc->wzText, &sczCloseRadioButton);
2444 BalExitOnFailure(hr, "Failed to format FilesInUseCloseRadioButton loc string.");
2445
2446 hr = BalFormatString(m_pFilesInUseDontCloseRadioButtonLoc->wzText, &sczDontCloseRadioButton);
2447 BalExitOnFailure(hr, "Failed to format FilesInUseDontCloseRadioButton loc string.");
2448
2449 const TASKDIALOG_BUTTON rgRadioButtons[] = {
2450 { IDOK, sczCloseRadioButton },
2451 { IDIGNORE, sczDontCloseRadioButton },
2452 };
2453
2454 config.cbSize = sizeof(config);
2455 config.hwndParent = m_hWnd;
2456 config.hInstance = m_hModule;
2457 config.dwFlags = TDF_SIZE_TO_CONTENT | TDF_POSITION_RELATIVE_TO_WINDOW;
2458 config.dwCommonButtons = TDCBF_OK_BUTTON | TDCBF_CANCEL_BUTTON;
2459 config.pszWindowTitle = sczTitle;
2460 config.pszMainInstruction = sczLabel;
2461 config.pszContent = sczFilesInUse ? sczFilesInUse : L"";
2462 config.nDefaultButton = IDOK;
2463 config.pRadioButtons = rgRadioButtons;
2464 config.cRadioButtons = countof(rgRadioButtons);
2465 config.nDefaultRadioButton = IDOK;
2466
2467 hr = ::TaskDialogIndirect(&config, &nButton, &nRadioButton, NULL);
2468 BalExitOnFailure(hr, "Failed to show RM files-in-use task dialog.");
2469
2470 *pnResult = IDOK == nButton ? nRadioButton : nButton;
2471
2472#ifdef DEBUG
2473 BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "WIXSTDBA: RMFilesInUse task dialog result: button - %d, radio button - %d, result - %d", nButton, nRadioButton, *pnResult);
2474#endif
2475
2476 LExit:
2477 ReleaseStr(sczTitle);
2478 ReleaseStr(sczLabel);
2479 ReleaseStr(sczCloseRadioButton);
2480 ReleaseStr(sczDontCloseRadioButton);
2481
2482 return hr;
2483 }
2484
2485
2486 int ShowStandardMsiFilesInUseDialog(
2487 __in_z_opt LPCWSTR sczFilesInUse,
2488 __out int* pnResult
2489 )
2490 {
2491 HRESULT hr = S_OK;
2492 TASKDIALOGCONFIG config = { };
2493 LPWSTR sczTitle = NULL;
2494 LPWSTR sczLabel = NULL;
2495 LPWSTR sczRetryButton = NULL;
2496 LPWSTR sczIgnoreButton = NULL;
2497 LPWSTR sczExitButton = NULL;
2498
2499 hr = BalFormatString(m_pFilesInUseTitleLoc->wzText, &sczTitle);
2500 BalExitOnFailure(hr, "Failed to format FilesInUseTitle loc string.");
2501
2502 hr = BalFormatString(m_pFilesInUseLabelLoc->wzText, &sczLabel);
2503 BalExitOnFailure(hr, "Failed to format FilesInUseLabel loc string.");
2504
2505 hr = BalFormatString(m_pFilesInUseRetryButtonLoc->wzText, &sczRetryButton);
2506 BalExitOnFailure(hr, "Failed to format FilesInUseRetryButton loc string.");
2507
2508 hr = BalFormatString(m_pFilesInUseIgnoreButtonLoc->wzText, &sczIgnoreButton);
2509 BalExitOnFailure(hr, "Failed to format FilesInUseIgnoreButton loc string.");
2510
2511 hr = BalFormatString(m_pFilesInUseExitButtonLoc->wzText, &sczExitButton);
2512 BalExitOnFailure(hr, "Failed to format FilesInUseExitButton loc string.");
2513
2514 const TASKDIALOG_BUTTON rgButtons[] = {
2515 { IDRETRY, sczRetryButton },
2516 { IDIGNORE, sczIgnoreButton },
2517 { IDCANCEL, sczExitButton },
2518 };
2519
2520 config.cbSize = sizeof(config);
2521 config.hwndParent = m_hWnd;
2522 config.hInstance = m_hModule;
2523 config.dwFlags = TDF_SIZE_TO_CONTENT | TDF_POSITION_RELATIVE_TO_WINDOW;
2524 config.pszWindowTitle = sczTitle;
2525 config.pszMainInstruction = sczLabel;
2526 config.pszContent = sczFilesInUse ? sczFilesInUse : L"";
2527 config.pButtons = rgButtons;
2528 config.cButtons = countof(rgButtons);
2529
2530 hr = ::TaskDialogIndirect(&config, pnResult, NULL, NULL);
2531 BalExitOnFailure(hr, "Failed to show files-in-use task dialog.");
2532
2533#ifdef DEBUG
2534 BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "WIXSTDBA: FilesInUse task dialog result: %d", *pnResult);
2535#endif
2536
2537 LExit:
2538 ReleaseStr(sczTitle);
2539 ReleaseStr(sczLabel);
2540 ReleaseStr(sczRetryButton);
2541 ReleaseStr(sczIgnoreButton);
2542 ReleaseStr(sczExitButton);
2543
2544 return hr;
2545 }
2546
2547
2548 HRESULT ShowNetfxFilesInUse(
2549 __in DWORD cFiles,
2550 __in_ecount_z(cFiles) LPCWSTR* rgwzFiles,
2551 __inout int* pResult
2552 )
2553 {
2554 HRESULT hr = S_OK;
2555 LPWSTR sczFilesInUse = NULL;
2556 DWORD_PTR cchLen = 0;
2557 int nResult = IDERROR;
2558
2559 // If the user has chosen to ignore on a previously displayed "files in use" page,
2560 // we will return the same result for other cases. No need to display the page again.
2561 if (IDNO == m_nLastNetfxFilesInUseResult)
2562 {
2563 nResult = m_nLastNetfxFilesInUseResult;
2564 }
2565 else if (BOOTSTRAPPER_DISPLAY_FULL != m_command.display) // Only show files in use when using full display mode.
2566 {
2567 nResult = IDYES;
2568 }
2569 else
2570 {
2571 for (DWORD i = 0; i < cFiles; ++i)
2572 {
2573 hr = ::StringCchLengthW(rgwzFiles[i], STRSAFE_MAX_CCH, reinterpret_cast<UINT_PTR*>(&cchLen));
2574 BalExitOnFailure(hr, "Failed to calculate length of string.");
2575
2576 if (cchLen)
2577 {
2578 hr = StrAllocConcatFormatted(&sczFilesInUse, L"%ls\r\n", rgwzFiles[i]);
2579 BalExitOnFailure(hr, "Failed to concat files in use.");
2580 }
2581 }
2582
2583 // Show applications using the files.
2584 hr = ShowNetfxFilesInUseDialog(sczFilesInUse, &nResult);
2585 ExitOnFailure(hr, "Failed to show Netfx files-in-use dialog.");
2586 }
2587
2588 LExit:
2589 ReleaseStr(sczFilesInUse);
2590
2591 // Remember the answer from the user.
2592 m_nLastNetfxFilesInUseResult = FAILED(hr) ? IDERROR : nResult;
2593 *pResult = m_nLastNetfxFilesInUseResult;
2594
2595 return hr;
2596 }
2597
2598
2599 int ShowNetfxFilesInUseDialog(
2600 __in_z_opt LPCWSTR sczFilesInUse,
2601 __out int* pnResult
2602 )
2603 {
2604 HRESULT hr = S_OK;
2605 TASKDIALOGCONFIG config = { };
2606 LPWSTR sczTitle = NULL;
2607 LPWSTR sczLabel = NULL;
2608 LPWSTR sczNetfxCloseRadioButton = NULL;
2609 LPWSTR sczDontCloseRadioButton = NULL;
2610 int nButton = 0;
2611 int nRadioButton = 0;
2612
2613 hr = BalFormatString(m_pFilesInUseTitleLoc->wzText, &sczTitle);
2614 BalExitOnFailure(hr, "Failed to format FilesInUseTitle loc string.");
2615
2616 hr = BalFormatString(m_pFilesInUseLabelLoc->wzText, &sczLabel);
2617 BalExitOnFailure(hr, "Failed to format FilesInUseLabel loc string.");
2618
2619 hr = BalFormatString(m_pFilesInUseNetfxCloseRadioButtonLoc->wzText, &sczNetfxCloseRadioButton);
2620 BalExitOnFailure(hr, "Failed to format FilesInUseNetfxCloseRadioButton loc string.");
2621
2622 hr = BalFormatString(m_pFilesInUseDontCloseRadioButtonLoc->wzText, &sczDontCloseRadioButton);
2623 BalExitOnFailure(hr, "Failed to format FilesInUseDontCloseRadioButton loc string.");
2624
2625 const TASKDIALOG_BUTTON rgRadioButtons[] = {
2626 { IDYES, sczNetfxCloseRadioButton },
2627 { IDNO, sczDontCloseRadioButton },
2628 };
2629
2630 config.cbSize = sizeof(config);
2631 config.hwndParent = m_hWnd;
2632 config.hInstance = m_hModule;
2633 config.dwFlags = TDF_SIZE_TO_CONTENT | TDF_POSITION_RELATIVE_TO_WINDOW;
2634 config.dwCommonButtons = TDCBF_RETRY_BUTTON | TDCBF_OK_BUTTON | TDCBF_CANCEL_BUTTON;
2635 config.pszWindowTitle = sczTitle;
2636 config.pszMainInstruction = sczLabel;
2637 config.pszContent = sczFilesInUse ? sczFilesInUse : L"";
2638 config.nDefaultButton = IDRETRY;
2639 config.pRadioButtons = rgRadioButtons;
2640 config.cRadioButtons = countof(rgRadioButtons);
2641 config.nDefaultRadioButton = IDYES;
2642
2643 hr = ::TaskDialogIndirect(&config, &nButton, &nRadioButton, NULL);
2644 BalExitOnFailure(hr, "Failed to show Netfx files-in-use task dialog.");
2645
2646 *pnResult = IDOK == nButton ? nRadioButton : nButton;
2647
2648#ifdef DEBUG
2649 BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "WIXSTDBA: NetfxFilesInUse task dialog result: button - %d, radio button - %d, result - %d", nButton, nRadioButton, *pnResult);
2650#endif
2651
2652 LExit:
2653 ReleaseStr(sczTitle);
2654 ReleaseStr(sczLabel);
2655 ReleaseStr(sczNetfxCloseRadioButton);
2656 ReleaseStr(sczDontCloseRadioButton);
2657
2658 return hr;
2659 }
2660
2661
2662public: //CBalBaseBootstrapperApplication
2663 virtual STDMETHODIMP Initialize(
2664 __in const BOOTSTRAPPER_CREATE_ARGS* pCreateArgs
2665 )
2666 {
2667 HRESULT hr = S_OK;
2668
2669 hr = __super::Initialize(pCreateArgs);
2670 BalExitOnFailure(hr, "CBalBaseBootstrapperApplication initialization failed.");
2671
2672 memcpy_s(&m_command, sizeof(m_command), pCreateArgs->pCommand, sizeof(BOOTSTRAPPER_COMMAND));
2673 memcpy_s(&m_createArgs, sizeof(m_createArgs), pCreateArgs, sizeof(BOOTSTRAPPER_CREATE_ARGS));
2674 m_createArgs.pCommand = &m_command;
2675
2676 hr = BalGetStringVariable(L"WixBundleVersion", &m_sczBundleVersion);
2677 BalExitOnFailure(hr, "CWixStandardBootstrapperApplication initialization failed.");
2678
2679 LExit:
2680 return hr;
2681 }
2682
2683 void Uninitialize(
2684 __in const BOOTSTRAPPER_DESTROY_ARGS* pArgs,
2685 __in BOOTSTRAPPER_DESTROY_RESULTS* /*pResults*/
2686 )
2687 {
2688 if (m_hBAFModule)
2689 {
2690 BA_FUNCTIONS_DESTROY_ARGS args = { };
2691 BA_FUNCTIONS_DESTROY_RESULTS results = { };
2692
2693 args.cbSize = sizeof(BA_FUNCTIONS_DESTROY_ARGS);
2694 args.fReload = pArgs->fReload;
2695
2696 results.cbSize = sizeof(BA_FUNCTIONS_DESTROY_RESULTS);
2697
2698 PFN_BA_FUNCTIONS_DESTROY pfnBAFunctionsDestroy = reinterpret_cast<PFN_BA_FUNCTIONS_DESTROY>(::GetProcAddress(m_hBAFModule, "BAFunctionsDestroy"));
2699 if (pfnBAFunctionsDestroy)
2700 {
2701 pfnBAFunctionsDestroy(&args, &results);
2702 }
2703
2704 if (!results.fDisableUnloading)
2705 {
2706 ::FreeLibrary(m_hBAFModule);
2707 m_hBAFModule = NULL;
2708 }
2709 }
2710 }
2711
2712
2713private:
2714 //
2715 // UiThreadProc - entrypoint for UI thread.
2716 //
2717 static DWORD WINAPI UiThreadProc(
2718 __in LPVOID pvContext
2719 )
2720 {
2721 HRESULT hr = S_OK;
2722 CWixStandardBootstrapperApplication* pThis = (CWixStandardBootstrapperApplication*)pvContext;
2723 BOOL fComInitialized = FALSE;
2724 BOOL fRet = FALSE;
2725 MSG msg = { };
2726 DWORD dwQuit = 0;
2727 WM_WIXSTDBA firstAction = WM_WIXSTDBA_DETECT_PACKAGES;
2728
2729 // Initialize COM and theme.
2730 hr = ::CoInitialize(NULL);
2731 BalExitOnFailure(hr, "Failed to initialize COM.");
2732 fComInitialized = TRUE;
2733
2734 hr = ThemeInitialize(pThis->m_hModule);
2735 BalExitOnFailure(hr, "Failed to initialize theme manager.");
2736
2737 hr = pThis->InitializeData();
2738 BalExitOnFailure(hr, "Failed to initialize data in bootstrapper application.");
2739
2740 // Create main window.
2741 pThis->InitializeTaskbarButton();
2742 hr = pThis->CreateMainWindow();
2743 BalExitOnFailure(hr, "Failed to create main window.");
2744
2745 if (FAILED(pThis->m_hrFinal))
2746 {
2747 pThis->SetState(WIXSTDBA_STATE_FAILED, hr);
2748 firstAction = WM_WIXSTDBA_SHOW_FAILURE;
2749 }
2750 else
2751 {
2752 // Okay, we're ready for packages now.
2753 pThis->SetState(WIXSTDBA_STATE_INITIALIZED, hr);
2754
2755 if (pThis->m_fPerformHelp && BOOTSTRAPPER_ACTION_HELP == pThis->m_command.action)
2756 {
2757 firstAction = WM_WIXSTDBA_SHOW_HELP;
2758 }
2759 }
2760
2761 ::PostMessageW(pThis->m_hWnd, firstAction, 0, 0);
2762
2763 // message pump
2764 while (0 != (fRet = ::GetMessageW(&msg, NULL, 0, 0)))
2765 {
2766 if (-1 == fRet)
2767 {
2768 hr = E_UNEXPECTED;
2769 BalExitOnFailure(hr, "Unexpected return value from message pump.");
2770 }
2771 else if (!ThemeHandleKeyboardMessage(pThis->m_pTheme, msg.hwnd, &msg))
2772 {
2773 ::TranslateMessage(&msg);
2774 ::DispatchMessageW(&msg);
2775 }
2776 }
2777
2778 // Succeeded thus far, check to see if anything went wrong while actually
2779 // executing changes.
2780 if (FAILED(pThis->m_hrFinal))
2781 {
2782 hr = pThis->m_hrFinal;
2783 }
2784 else if (pThis->CheckCanceled())
2785 {
2786 hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT);
2787 }
2788
2789 LExit:
2790 // destroy main window
2791 pThis->DestroyMainWindow();
2792 pThis->UninitializeTaskbarButton();
2793
2794 if (BOOTSTRAPPER_APPLY_RESTART_INITIATED == pThis->m_restartResult)
2795 {
2796 dwQuit = SUCCEEDED(hr) ? ERROR_SUCCESS_REBOOT_INITIATED : ERROR_FAIL_REBOOT_INITIATED;
2797 }
2798 else if (BOOTSTRAPPER_APPLY_RESTART_REQUIRED == pThis->m_restartResult)
2799 {
2800 dwQuit = SUCCEEDED(hr) ? ERROR_SUCCESS_REBOOT_REQUIRED : ERROR_FAIL_REBOOT_REQUIRED;
2801 }
2802 else if (SEVERITY_ERROR == HRESULT_SEVERITY(hr) && FACILITY_WIN32 == HRESULT_FACILITY(hr))
2803 {
2804 // Convert Win32 HRESULTs back to the error code.
2805 dwQuit = HRESULT_CODE(hr);
2806 }
2807 else
2808 {
2809 dwQuit = hr;
2810 }
2811
2812 // initiate engine shutdown
2813 pThis->m_pEngine->Quit(dwQuit);
2814
2815 ReleaseTheme(pThis->m_pTheme);
2816 ThemeUninitialize();
2817
2818 // uninitialize COM
2819 if (fComInitialized)
2820 {
2821 ::CoUninitialize();
2822 }
2823
2824 return hr;
2825 }
2826
2827
2828 //
2829 // InitializeData - initializes all the package and prerequisite information.
2830 //
2831 HRESULT InitializeData()
2832 {
2833 HRESULT hr = S_OK;
2834 LPWSTR sczModulePath = NULL;
2835 IXMLDOMDocument* pixdManifest = NULL;
2836
2837 hr = BalManifestLoad(m_hModule, &pixdManifest);
2838 BalExitOnFailure(hr, "Failed to load bootstrapper application manifest.");
2839
2840 hr = BalInfoParseFromXml(&m_Bundle, pixdManifest);
2841 BalExitOnFailure(hr, "Failed to load bundle information.");
2842
2843 hr = ProcessCommandLine(&m_sczLanguage);
2844 ExitOnFailure(hr, "Unknown commandline parameters.");
2845
2846 hr = PathRelativeToModule(&sczModulePath, NULL, m_hModule);
2847 BalExitOnFailure(hr, "Failed to get module path.");
2848
2849 hr = LoadLocalization(sczModulePath, m_sczLanguage);
2850 ExitOnFailure(hr, "Failed to load localization.");
2851
2852 LoadFilesInUse();
2853
2854 hr = LoadTheme(sczModulePath, m_sczLanguage);
2855 ExitOnFailure(hr, "Failed to load theme.");
2856
2857 hr = BalConditionsParseFromXml(&m_Conditions, pixdManifest, m_pWixLoc);
2858 BalExitOnFailure(hr, "Failed to load conditions from XML.");
2859
2860 hr = LoadBAFunctions(pixdManifest);
2861 BalExitOnFailure(hr, "Failed to load bootstrapper functions.");
2862
2863 GetBundleFileVersion();
2864 // don't fail if we couldn't get the version info; best-effort only
2865
2866 if (m_fPrereq)
2867 {
2868 hr = InitializePrerequisiteInformation();
2869 BalExitOnFailure(hr, "Failed to initialize prerequisite information.");
2870 }
2871 else
2872 {
2873 hr = ParseBootstrapperApplicationDataFromXml(pixdManifest);
2874 BalExitOnFailure(hr, "Failed to read bootstrapper application data.");
2875 }
2876
2877 if (m_fRequestedCacheOnly)
2878 {
2879 if (m_fSupportCacheOnly)
2880 {
2881 // Doesn't make sense to prompt the user if cache only is requested.
2882 if (BOOTSTRAPPER_DISPLAY_PASSIVE < m_command.display)
2883 {
2884 m_command.display = BOOTSTRAPPER_DISPLAY_PASSIVE;
2885 }
2886
2887 m_command.action = BOOTSTRAPPER_ACTION_CACHE;
2888 }
2889 else
2890 {
2891 BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Ignoring attempt to only cache a bundle that does not explicitly support it.");
2892 }
2893 }
2894
2895 LExit:
2896 ReleaseObject(pixdManifest);
2897 ReleaseStr(sczModulePath);
2898
2899 return hr;
2900 }
2901
2902
2903 //
2904 // ProcessCommandLine - process the provided command line arguments.
2905 //
2906 HRESULT ProcessCommandLine(
2907 __inout LPWSTR* psczLanguage
2908 )
2909 {
2910 HRESULT hr = S_OK;
2911 int argc = 0;
2912 LPWSTR* argv = NULL;
2913 BOOL fUnknownArg = FALSE;
2914
2915 argc = m_BalInfoCommand.cUnknownArgs;
2916 argv = m_BalInfoCommand.rgUnknownArgs;
2917
2918 if (argc)
2919 {
2920 for (int i = 0; i < argc; ++i)
2921 {
2922 fUnknownArg = FALSE;
2923
2924 if (argv[i][0] == L'-' || argv[i][0] == L'/')
2925 {
2926 if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, L"lang", -1))
2927 {
2928 if (i + 1 >= argc)
2929 {
2930 hr = E_INVALIDARG;
2931 BalExitOnFailure(hr, "Must specify a language.");
2932 }
2933
2934 ++i;
2935
2936 hr = StrAllocString(psczLanguage, &argv[i][0], 0);
2937 BalExitOnFailure(hr, "Failed to copy language.");
2938 }
2939 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, L"cache", -1))
2940 {
2941 m_fRequestedCacheOnly = TRUE;
2942 }
2943 else
2944 {
2945 fUnknownArg = TRUE;
2946 }
2947 }
2948 else
2949 {
2950 fUnknownArg = TRUE;
2951 }
2952
2953 if (fUnknownArg)
2954 {
2955 BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Ignoring unknown argument: %ls", argv[i]);
2956 }
2957 }
2958 }
2959
2960 hr = BalSetOverridableVariablesFromEngine(&m_Bundle.overridableVariables, &m_BalInfoCommand, m_pEngine);
2961 BalExitOnFailure(hr, "Failed to set overridable variables from the command line.");
2962
2963 LExit:
2964 return hr;
2965 }
2966
2967 HRESULT LoadLocalization(
2968 __in_z LPCWSTR wzModulePath,
2969 __in_z_opt LPCWSTR wzLanguage
2970 )
2971 {
2972 HRESULT hr = S_OK;
2973 LPWSTR sczLocPath = NULL;
2974 LPWSTR sczFormatted = NULL;
2975 LPCWSTR wzLocFileName = m_fPrereq ? L"mbapreq.wxl" : L"thm.wxl";
2976
2977 // Find and load .wxl file.
2978 hr = LocProbeForFile(wzModulePath, wzLocFileName, wzLanguage, &sczLocPath);
2979 BalExitOnFailure(hr, "Failed to probe for loc file: %ls in path: %ls", wzLocFileName, wzModulePath);
2980
2981 hr = LocLoadFromFile(sczLocPath, &m_pWixLoc);
2982 BalExitOnFailure(hr, "Failed to load loc file from path: %ls", sczLocPath);
2983
2984 // Set WixStdBALanguageId to .wxl language id.
2985 if (WIX_LOCALIZATION_LANGUAGE_NOT_SET != m_pWixLoc->dwLangId)
2986 {
2987 ::SetThreadLocale(m_pWixLoc->dwLangId);
2988
2989 hr = m_pEngine->SetVariableNumeric(WIXSTDBA_VARIABLE_LANGUAGE_ID, m_pWixLoc->dwLangId);
2990 BalExitOnFailure(hr, "Failed to set WixStdBALanguageId variable.");
2991 }
2992
2993 // Load ConfirmCancelMessage.
2994 hr = StrAllocString(&m_sczConfirmCloseMessage, L"#(loc.ConfirmCancelMessage)", 0);
2995 ExitOnFailure(hr, "Failed to initialize confirm message loc identifier.");
2996
2997 hr = LocLocalizeString(m_pWixLoc, &m_sczConfirmCloseMessage);
2998 BalExitOnFailure(hr, "Failed to localize confirm close message: %ls", m_sczConfirmCloseMessage);
2999
3000 hr = BalFormatString(m_sczConfirmCloseMessage, &sczFormatted);
3001 if (SUCCEEDED(hr))
3002 {
3003 ReleaseStr(m_sczConfirmCloseMessage);
3004 m_sczConfirmCloseMessage = sczFormatted;
3005 sczFormatted = NULL;
3006 }
3007
3008 LExit:
3009 ReleaseStr(sczFormatted);
3010 ReleaseStr(sczLocPath);
3011
3012 return hr;
3013 }
3014
3015
3016 HRESULT LoadIndividualLocString(
3017 __in_z LPCWSTR wzId,
3018 __out LOC_STRING** ppLocString
3019 )
3020 {
3021 HRESULT hr = LocGetString(m_pWixLoc, wzId, ppLocString);
3022
3023 if (E_NOTFOUND == hr)
3024 {
3025 BalLog(BOOTSTRAPPER_LOG_LEVEL_DEBUG, "WIXSTDBA: Missing loc string '%ls'.", wzId);
3026 }
3027
3028 return hr;
3029 }
3030
3031
3032 void LoadFilesInUse()
3033 {
3034 // Get the loc strings for the files-in-use dialogs.
3035 LoadIndividualLocString(L"#(loc.FilesInUseTitle)", &m_pFilesInUseTitleLoc);
3036 LoadIndividualLocString(L"#(loc.FilesInUseLabel)", &m_pFilesInUseLabelLoc);
3037 LoadIndividualLocString(L"#(loc.FilesInUseCloseRadioButton)", &m_pFilesInUseCloseRadioButtonLoc);
3038 LoadIndividualLocString(L"#(loc.FilesInUseDontCloseRadioButton)", &m_pFilesInUseDontCloseRadioButtonLoc);
3039 LoadIndividualLocString(L"#(loc.FilesInUseRetryButton)", &m_pFilesInUseRetryButtonLoc);
3040 LoadIndividualLocString(L"#(loc.FilesInUseIgnoreButton)", &m_pFilesInUseIgnoreButtonLoc);
3041 LoadIndividualLocString(L"#(loc.FilesInUseExitButton)", &m_pFilesInUseExitButtonLoc);
3042 LoadIndividualLocString(L"#(loc.FilesInUseNetfxCloseRadioButton)", &m_pFilesInUseNetfxCloseRadioButtonLoc);
3043
3044 m_fShowRMFilesInUse = m_pFilesInUseTitleLoc && m_pFilesInUseLabelLoc && m_pFilesInUseCloseRadioButtonLoc && m_pFilesInUseDontCloseRadioButtonLoc;
3045 m_fShowStandardFilesInUse = m_pFilesInUseTitleLoc && m_pFilesInUseLabelLoc && m_pFilesInUseRetryButtonLoc && m_pFilesInUseIgnoreButtonLoc && m_pFilesInUseExitButtonLoc;
3046 m_fShowNetfxFilesInUse = m_pFilesInUseTitleLoc && m_pFilesInUseLabelLoc && m_pFilesInUseNetfxCloseRadioButtonLoc && m_pFilesInUseDontCloseRadioButtonLoc;
3047 }
3048
3049
3050 HRESULT LoadTheme(
3051 __in_z LPCWSTR wzModulePath,
3052 __in_z_opt LPCWSTR wzLanguage
3053 )
3054 {
3055 HRESULT hr = S_OK;
3056 LPWSTR sczThemePath = NULL;
3057 LPCWSTR wzThemeFileName = m_fPrereq ? L"mbapreq.thm" : L"thm.xml";
3058
3059 hr = LocProbeForFile(wzModulePath, wzThemeFileName, wzLanguage, &sczThemePath);
3060 BalExitOnFailure(hr, "Failed to probe for theme file: %ls in path: %ls", wzThemeFileName, wzModulePath);
3061
3062 hr = ThemeLoadFromFile(sczThemePath, &m_pTheme);
3063 BalExitOnFailure(hr, "Failed to load theme from path: %ls", sczThemePath);
3064
3065 hr = ThemeRegisterVariableCallbacks(m_pTheme, EvaluateVariableConditionCallback, FormatVariableStringCallback, GetVariableNumericCallback, SetVariableNumericCallback, GetVariableStringCallback, SetVariableStringCallback, NULL);
3066 BalExitOnFailure(hr, "Failed to register variable theme callbacks.");
3067
3068 C_ASSERT(COUNT_WIXSTDBA_PAGE == countof(vrgwzPageNames));
3069 C_ASSERT(countof(m_rgdwPageIds) == countof(vrgwzPageNames));
3070
3071 ThemeGetPageIds(m_pTheme, vrgwzPageNames, m_rgdwPageIds, countof(m_rgdwPageIds));
3072
3073 hr = ThemeLocalize(m_pTheme, m_pWixLoc);
3074 BalExitOnFailure(hr, "Failed to localize theme: %ls", sczThemePath);
3075
3076 LExit:
3077 ReleaseStr(sczThemePath);
3078
3079 return hr;
3080 }
3081
3082
3083 HRESULT InitializePrerequisiteInformation()
3084 {
3085 HRESULT hr = S_OK;
3086 BAL_INFO_PACKAGE* pPackage = NULL;
3087
3088 for (DWORD i = 0; i < m_Bundle.packages.cPackages; ++i)
3089 {
3090 pPackage = &m_Bundle.packages.rgPackages[i];
3091 if (!pPackage->fPrereqPackage)
3092 {
3093 continue;
3094 }
3095
3096 if (pPackage->sczPrereqLicenseFile)
3097 {
3098 if (m_sczLicenseFile)
3099 {
3100 hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
3101 BalExitOnFailure(hr, "More than one license file specified in prerequisite info.");
3102 }
3103
3104 hr = StrAllocString(&m_sczLicenseFile, pPackage->sczPrereqLicenseFile, 0);
3105 BalExitOnFailure(hr, "Failed to copy license file location from prereq package.");
3106 }
3107
3108 if (pPackage->sczPrereqLicenseUrl)
3109 {
3110 if (m_sczLicenseUrl)
3111 {
3112 hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
3113 BalExitOnFailure(hr, "More than one license URL specified in prerequisite info.");
3114 }
3115
3116 hr = StrAllocString(&m_sczLicenseUrl, pPackage->sczPrereqLicenseUrl, 0);
3117 BalExitOnFailure(hr, "Failed to copy license URL from prereq package.");
3118 }
3119 }
3120
3121 LExit:
3122 return hr;
3123 }
3124
3125
3126 HRESULT ParseBootstrapperApplicationDataFromXml(
3127 __in IXMLDOMDocument* pixdManifest
3128 )
3129 {
3130 HRESULT hr = S_OK;
3131 IXMLDOMNode* pNode = NULL;
3132 DWORD dwBool = 0;
3133 BOOL fXmlFound = FALSE;
3134
3135 hr = XmlSelectSingleNode(pixdManifest, L"/BootstrapperApplicationData/WixStdbaInformation", &pNode);
3136 BalExitOnRequiredXmlQueryFailure(hr, "BootstrapperApplication.xml manifest is missing wixstdba information.");
3137
3138 hr = XmlGetAttributeEx(pNode, L"LicenseFile", &m_sczLicenseFile);
3139 BalExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to get license file.");
3140
3141 hr = XmlGetAttributeEx(pNode, L"LicenseUrl", &m_sczLicenseUrl);
3142 BalExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to get license URL.");
3143
3144 ReleaseObject(pNode);
3145
3146 hr = XmlSelectSingleNode(pixdManifest, L"/BootstrapperApplicationData/WixStdbaOptions", &pNode);
3147 BalExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to read wixstdba options from BootstrapperApplication.xml manifest.");
3148
3149 if (!fXmlFound)
3150 {
3151 ExitFunction();
3152 }
3153
3154 hr = XmlGetAttributeNumber(pNode, L"SuppressOptionsUI", &dwBool);
3155 BalExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to get SuppressOptionsUI value.");
3156
3157 if (fXmlFound && dwBool)
3158 {
3159 hr = BalSetNumericVariable(WIXSTDBA_VARIABLE_SUPPRESS_OPTIONS_UI, 1);
3160 BalExitOnFailure(hr, "Failed to set '%ls' variable.", WIXSTDBA_VARIABLE_SUPPRESS_OPTIONS_UI);
3161 }
3162
3163 dwBool = 0;
3164 hr = XmlGetAttributeNumber(pNode, L"SuppressDowngradeFailure", &dwBool);
3165 BalExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to get SuppressDowngradeFailure value.");
3166
3167 if (fXmlFound)
3168 {
3169 m_fSuppressDowngradeFailure = 0 < dwBool;
3170 }
3171
3172 dwBool = 0;
3173 hr = XmlGetAttributeNumber(pNode, L"SuppressRepair", &dwBool);
3174 BalExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to get SuppressRepair value.");
3175
3176 if (fXmlFound)
3177 {
3178 m_fSuppressRepair = 0 < dwBool;
3179 }
3180
3181 hr = XmlGetAttributeNumber(pNode, L"ShowVersion", &dwBool);
3182 BalExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to get ShowVersion value.");
3183
3184 if (fXmlFound && dwBool)
3185 {
3186 hr = BalSetNumericVariable(WIXSTDBA_VARIABLE_SHOW_VERSION, 1);
3187 BalExitOnFailure(hr, "Failed to set '%ls' variable.", WIXSTDBA_VARIABLE_SHOW_VERSION);
3188 }
3189
3190 hr = XmlGetAttributeNumber(pNode, L"SupportCacheOnly", &dwBool);
3191 BalExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to get SupportCacheOnly value.");
3192
3193 if (fXmlFound)
3194 {
3195 m_fSupportCacheOnly = 0 < dwBool;
3196 }
3197
3198 LExit:
3199 ReleaseObject(pNode);
3200 return hr;
3201 }
3202
3203
3204 //
3205 // Get the file version of the bootstrapper and record in bootstrapper log file
3206 //
3207 HRESULT GetBundleFileVersion()
3208 {
3209 HRESULT hr = S_OK;
3210 ULARGE_INTEGER uliVersion = { };
3211 LPWSTR sczCurrentPath = NULL;
3212 VERUTIL_VERSION* pVersion = NULL;
3213
3214 hr = PathForCurrentProcess(&sczCurrentPath, NULL);
3215 BalExitOnFailure(hr, "Failed to get bundle path.");
3216
3217 hr = FileVersion(sczCurrentPath, &uliVersion.HighPart, &uliVersion.LowPart);
3218 BalExitOnFailure(hr, "Failed to get bundle file version.");
3219
3220 hr = VerVersionFromQword(uliVersion.QuadPart, &pVersion);
3221 BalExitOnFailure(hr, "Failed to create bundle file version.");
3222
3223 hr = m_pEngine->SetVariableVersion(WIXSTDBA_VARIABLE_BUNDLE_FILE_VERSION, pVersion->sczVersion);
3224 BalExitOnFailure(hr, "Failed to set WixBundleFileVersion variable.");
3225
3226 LExit:
3227 ReleaseVerutilVersion(pVersion);
3228 ReleaseStr(sczCurrentPath);
3229
3230 return hr;
3231 }
3232
3233
3234 //
3235 // CreateMainWindow - creates the main install window.
3236 //
3237 HRESULT CreateMainWindow()
3238 {
3239 HRESULT hr = S_OK;
3240 WNDCLASSW wc = { };
3241 DWORD dwWindowStyle = 0;
3242 int x = CW_USEDEFAULT;
3243 int y = CW_USEDEFAULT;
3244 POINT ptCursor = { };
3245
3246 ThemeInitializeWindowClass(m_pTheme, &wc, CWixStandardBootstrapperApplication::WndProc, m_hModule, WIXSTDBA_WINDOW_CLASS);
3247
3248 // If the theme did not provide an icon, try using the icon from the bundle engine.
3249 if (!wc.hIcon)
3250 {
3251 HMODULE hBootstrapperEngine = ::GetModuleHandleW(NULL);
3252 if (hBootstrapperEngine)
3253 {
3254 wc.hIcon = ::LoadIconW(hBootstrapperEngine, MAKEINTRESOURCEW(1));
3255 }
3256 }
3257
3258 // Register the window class and create the window.
3259 if (!::RegisterClassW(&wc))
3260 {
3261 ExitWithLastError(hr, "Failed to register window.");
3262 }
3263
3264 m_fRegistered = TRUE;
3265
3266 // Calculate the window style based on the theme style and command display value.
3267 dwWindowStyle = m_pTheme->dwStyle;
3268 if (BOOTSTRAPPER_DISPLAY_NONE >= m_command.display || m_fPreplanPrereqs)
3269 {
3270 dwWindowStyle &= ~WS_VISIBLE;
3271 }
3272
3273 // Don't show the window if there is a splash screen (it will be made visible when the splash screen is hidden)
3274 if (::IsWindow(m_command.hwndSplashScreen))
3275 {
3276 dwWindowStyle &= ~WS_VISIBLE;
3277 }
3278
3279 // Center the window on the monitor with the mouse.
3280 if (::GetCursorPos(&ptCursor))
3281 {
3282 x = ptCursor.x;
3283 y = ptCursor.y;
3284 }
3285
3286 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);
3287 ExitOnFailure(hr, "Failed to create window.");
3288
3289 OnThemeLoaded();
3290
3291 hr = S_OK;
3292
3293 LExit:
3294 return hr;
3295 }
3296
3297
3298 //
3299 // InitializeTaskbarButton - initializes taskbar button for progress.
3300 //
3301 void InitializeTaskbarButton()
3302 {
3303 HRESULT hr = S_OK;
3304
3305 hr = ::CoCreateInstance(CLSID_TaskbarList, NULL, CLSCTX_ALL, __uuidof(ITaskbarList3), reinterpret_cast<LPVOID*>(&m_pTaskbarList));
3306 if (REGDB_E_CLASSNOTREG == hr) // not supported before Windows 7
3307 {
3308 ExitFunction1(hr = S_OK);
3309 }
3310 BalExitOnFailure(hr, "Failed to create ITaskbarList3. Continuing.");
3311
3312 m_uTaskbarButtonCreatedMessage = ::RegisterWindowMessageW(L"TaskbarButtonCreated");
3313 BalExitOnNullWithLastError(m_uTaskbarButtonCreatedMessage, hr, "Failed to get TaskbarButtonCreated message. Continuing.");
3314
3315 LExit:
3316 return;
3317 }
3318
3319 //
3320 // DestroyMainWindow - clean up all the window registration.
3321 //
3322 void DestroyMainWindow()
3323 {
3324 if (::IsWindow(m_hWnd))
3325 {
3326 ::DestroyWindow(m_hWnd);
3327 m_hWnd = NULL;
3328 m_fTaskbarButtonOK = FALSE;
3329 }
3330
3331 if (m_fRegistered)
3332 {
3333 ::UnregisterClassW(WIXSTDBA_WINDOW_CLASS, m_hModule);
3334 m_fRegistered = FALSE;
3335 }
3336 }
3337
3338
3339 //
3340 // UninitializeTaskbarButton - clean up the taskbar registration.
3341 //
3342 void UninitializeTaskbarButton()
3343 {
3344 m_fTaskbarButtonOK = FALSE;
3345 ReleaseNullObject(m_pTaskbarList);
3346 }
3347
3348
3349 static LRESULT CallDefaultWndProc(
3350 __in CWixStandardBootstrapperApplication* pBA,
3351 __in HWND hWnd,
3352 __in UINT uMsg,
3353 __in WPARAM wParam,
3354 __in LPARAM lParam
3355 )
3356 {
3357 LRESULT lres = NULL;
3358 THEME* pTheme = NULL;
3359 HRESULT hr = S_OK;
3360 BA_FUNCTIONS_WNDPROC_ARGS wndProcArgs = { };
3361 BA_FUNCTIONS_WNDPROC_RESULTS wndProcResults = { };
3362
3363 if (pBA)
3364 {
3365 pTheme = pBA->m_pTheme;
3366
3367 if (pBA->m_pfnBAFunctionsProc)
3368 {
3369 wndProcArgs.cbSize = sizeof(wndProcArgs);
3370 wndProcArgs.hWnd = hWnd;
3371 wndProcArgs.uMsg = uMsg;
3372 wndProcArgs.wParam = wParam;
3373 wndProcArgs.lParam = lParam;
3374 wndProcResults.cbSize = sizeof(wndProcResults);
3375
3376 hr = pBA->m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_WNDPROC, &wndProcArgs, &wndProcResults, pBA->m_pvBAFunctionsProcContext);
3377
3378 if (E_NOTIMPL == hr)
3379 {
3380 hr = S_OK;
3381 }
3382 else
3383 {
3384 BalExitOnFailure(hr, "BAFunctions WndProc failed.");
3385
3386 if (wndProcResults.fProcessed)
3387 {
3388 lres = wndProcResults.lResult;
3389 ExitFunction();
3390 }
3391 }
3392 }
3393 }
3394
3395 lres = ThemeDefWindowProc(pTheme, hWnd, uMsg, wParam, lParam);
3396
3397 LExit:
3398 return lres;
3399 }
3400
3401 //
3402 // WndProc - standard windows message handler.
3403 //
3404 static LRESULT CALLBACK WndProc(
3405 __in HWND hWnd,
3406 __in UINT uMsg,
3407 __in WPARAM wParam,
3408 __in LPARAM lParam
3409 )
3410 {
3411#pragma warning(suppress:4312)
3412 CWixStandardBootstrapperApplication* pBA = reinterpret_cast<CWixStandardBootstrapperApplication*>(::GetWindowLongPtrW(hWnd, GWLP_USERDATA));
3413
3414 switch (uMsg)
3415 {
3416 case WM_NCCREATE:
3417 {
3418 LPCREATESTRUCT lpcs = reinterpret_cast<LPCREATESTRUCT>(lParam);
3419 pBA = reinterpret_cast<CWixStandardBootstrapperApplication*>(lpcs->lpCreateParams);
3420#pragma warning(suppress:4244)
3421 ::SetWindowLongPtrW(hWnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(pBA));
3422 }
3423 break;
3424
3425 case WM_NCDESTROY:
3426 {
3427 LRESULT lres = CallDefaultWndProc(pBA, hWnd, uMsg, wParam, lParam);
3428 ::SetWindowLongPtrW(hWnd, GWLP_USERDATA, 0);
3429 ::PostQuitMessage(0);
3430 return lres;
3431 }
3432
3433 case WM_THMUTIL_LOADING_CONTROL:
3434 return pBA->OnThemeLoadingControl(reinterpret_cast<THEME_LOADINGCONTROL_ARGS*>(wParam), reinterpret_cast<THEME_LOADINGCONTROL_RESULTS*>(lParam));
3435
3436 case WM_THMUTIL_LOADED_CONTROL:
3437 return pBA->OnThemeLoadedControl(reinterpret_cast<THEME_LOADEDCONTROL_ARGS*>(wParam), reinterpret_cast<THEME_LOADEDCONTROL_RESULTS*>(lParam));
3438
3439 case WM_CLOSE:
3440 // If the user chose not to close, do *not* let the default window proc handle the message.
3441 if (!pBA->OnClose())
3442 {
3443 return 0;
3444 }
3445 break;
3446
3447 case WM_WIXSTDBA_SHOW_HELP:
3448 pBA->OnShowHelp();
3449 return 0;
3450
3451 case WM_WIXSTDBA_DETECT_PACKAGES:
3452 pBA->OnDetect();
3453 return 0;
3454
3455 case WM_WIXSTDBA_PLAN_PACKAGES:
3456 pBA->OnPlan(static_cast<BOOTSTRAPPER_ACTION>(lParam));
3457 return 0;
3458
3459 case WM_WIXSTDBA_APPLY_PACKAGES:
3460 pBA->OnApply();
3461 return 0;
3462
3463 case WM_WIXSTDBA_CHANGE_STATE:
3464 pBA->OnChangeState(static_cast<WIXSTDBA_STATE>(lParam));
3465 return 0;
3466
3467 case WM_WIXSTDBA_SHOW_FAILURE:
3468 pBA->OnShowFailure();
3469 return 0;
3470
3471 case WM_WIXSTDBA_PLAN_PREREQS:
3472 pBA->OnPlanPrereqs(static_cast<BOOTSTRAPPER_ACTION>(lParam));
3473 return 0;
3474
3475 case WM_THMUTIL_CONTROL_WM_COMMAND:
3476 return pBA->OnThemeControlWmCommand(reinterpret_cast<THEME_CONTROLWMCOMMAND_ARGS*>(wParam), reinterpret_cast<THEME_CONTROLWMCOMMAND_RESULTS*>(lParam));
3477
3478 case WM_THMUTIL_CONTROL_WM_NOTIFY:
3479 return pBA->OnThemeControlWmNotify(reinterpret_cast<THEME_CONTROLWMNOTIFY_ARGS*>(wParam), reinterpret_cast<THEME_CONTROLWMNOTIFY_RESULTS*>(lParam));
3480 }
3481
3482 if (pBA && pBA->m_pTaskbarList && uMsg == pBA->m_uTaskbarButtonCreatedMessage)
3483 {
3484 pBA->m_fTaskbarButtonOK = TRUE;
3485 return 0;
3486 }
3487
3488 return CallDefaultWndProc(pBA, hWnd, uMsg, wParam, lParam);
3489 }
3490
3491
3492 //
3493 // OnThemeLoaded - finishes loading the theme.
3494 //
3495 BOOL OnThemeLoaded()
3496 {
3497 HRESULT hr = S_OK;
3498 BA_FUNCTIONS_ONTHEMELOADED_ARGS themeLoadedArgs = { };
3499 BA_FUNCTIONS_ONTHEMELOADED_RESULTS themeLoadedResults = { };
3500
3501 if (m_pfnBAFunctionsProc)
3502 {
3503 themeLoadedArgs.cbSize = sizeof(themeLoadedArgs);
3504 themeLoadedArgs.hWnd = m_pTheme->hwndParent;
3505 themeLoadedResults.cbSize = sizeof(themeLoadedResults);
3506 hr = m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONTHEMELOADED, &themeLoadedArgs, &themeLoadedResults, m_pvBAFunctionsProcContext);
3507 BalExitOnFailure(hr, "BAFunctions OnThemeLoaded failed.");
3508 }
3509
3510 LExit:
3511 return SUCCEEDED(hr);
3512 }
3513
3514 BOOL OnThemeLoadingControl(
3515 __in const THEME_LOADINGCONTROL_ARGS* pArgs,
3516 __in THEME_LOADINGCONTROL_RESULTS* pResults
3517 )
3518 {
3519 HRESULT hr = S_OK;
3520 BOOL fProcessed = FALSE;
3521 BA_FUNCTIONS_ONTHEMECONTROLLOADING_ARGS themeControlLoadingArgs = { };
3522 BA_FUNCTIONS_ONTHEMECONTROLLOADING_RESULTS themeControlLoadingResults = { };
3523
3524 for (DWORD iAssignControl = 0; iAssignControl < countof(m_rgInitControls); ++iAssignControl)
3525 {
3526 THEME_ASSIGN_CONTROL_ID* pAssignControl = m_rgInitControls + iAssignControl;
3527 if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, pArgs->pThemeControl->sczName, -1, pAssignControl->wzName, -1))
3528 {
3529 if (!pAssignControl->ppControl)
3530 {
3531 BalExitWithRootFailure(hr, E_INVALIDSTATE, "Control '%ls' has no member variable", pAssignControl->wzName);
3532 }
3533
3534 if (*pAssignControl->ppControl)
3535 {
3536 BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Duplicate control name: %ls", pAssignControl->wzName);
3537 }
3538 else
3539 {
3540 *pAssignControl->ppControl = pArgs->pThemeControl;
3541 }
3542
3543 fProcessed = TRUE;
3544 pResults->wId = pAssignControl->wId;
3545 pResults->dwAutomaticBehaviorType = pAssignControl->dwAutomaticBehaviorType;
3546 ExitFunction();
3547 }
3548 }
3549
3550 if (m_pfnBAFunctionsProc)
3551 {
3552 themeControlLoadingArgs.cbSize = sizeof(themeControlLoadingArgs);
3553 themeControlLoadingArgs.wzName = pArgs->pThemeControl->sczName;
3554
3555 themeControlLoadingResults.cbSize = sizeof(themeControlLoadingResults);
3556 themeControlLoadingResults.wId = pResults->wId;
3557 themeControlLoadingResults.dwAutomaticBehaviorType = pResults->dwAutomaticBehaviorType;
3558
3559 hr = m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONTHEMECONTROLLOADING, &themeControlLoadingArgs, &themeControlLoadingResults, m_pvBAFunctionsProcContext);
3560
3561 if (E_NOTIMPL == hr)
3562 {
3563 hr = S_OK;
3564 }
3565 else
3566 {
3567 BalExitOnFailure(hr, "BAFunctions OnThemeControlLoading failed.");
3568
3569 if (themeControlLoadingResults.fProcessed)
3570 {
3571 fProcessed = TRUE;
3572 pResults->wId = themeControlLoadingResults.wId;
3573 pResults->dwAutomaticBehaviorType = themeControlLoadingResults.dwAutomaticBehaviorType;
3574 }
3575 }
3576 }
3577
3578 LExit:
3579 pResults->hr = hr;
3580 return fProcessed || FAILED(hr);
3581 }
3582
3583 BOOL OnThemeLoadedControl(
3584 __in const THEME_LOADEDCONTROL_ARGS* pArgs,
3585 __in THEME_LOADEDCONTROL_RESULTS* pResults
3586 )
3587 {
3588 HRESULT hr = S_OK;
3589 BOOL fProcessed = FALSE;
3590 BA_FUNCTIONS_ONTHEMECONTROLLOADED_ARGS themeControlLoadedArgs = { };
3591 BA_FUNCTIONS_ONTHEMECONTROLLOADED_RESULTS themeControlLoadedResults = { };
3592
3593 if (WIXSTDBA_CONTROL_EULA_RICHEDIT == pArgs->pThemeControl->wId)
3594 {
3595 // Best effort to load the RTF EULA control with text.
3596 OnLoadedEulaRtfControl(pArgs->pThemeControl);
3597 fProcessed = TRUE;
3598 ExitFunction();
3599 }
3600
3601 if (m_pfnBAFunctionsProc)
3602 {
3603 themeControlLoadedArgs.cbSize = sizeof(themeControlLoadedArgs);
3604 themeControlLoadedArgs.wzName = pArgs->pThemeControl->sczName;
3605 themeControlLoadedArgs.wId = pArgs->pThemeControl->wId;
3606 themeControlLoadedArgs.hWnd = pArgs->pThemeControl->hWnd;
3607
3608 themeControlLoadedResults.cbSize = sizeof(themeControlLoadedResults);
3609
3610 hr = m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONTHEMECONTROLLOADED, &themeControlLoadedArgs, &themeControlLoadedResults, m_pvBAFunctionsProcContext);
3611
3612 if (E_NOTIMPL == hr)
3613 {
3614 hr = S_OK;
3615 }
3616 else
3617 {
3618 BalExitOnFailure(hr, "BAFunctions OnThemeControlLoaded failed.");
3619
3620 if (themeControlLoadedResults.fProcessed)
3621 {
3622 fProcessed = TRUE;
3623 }
3624 }
3625 }
3626
3627 LExit:
3628 pResults->hr = hr;
3629 return fProcessed || FAILED(hr);
3630 }
3631
3632 HRESULT OnLoadedEulaRtfControl(
3633 const THEME_CONTROL* pThemeControl
3634 )
3635 {
3636 HRESULT hr = S_OK;
3637 LPWSTR sczLicenseFormatted = NULL;
3638 LPWSTR sczLicensePath = NULL;
3639 LPWSTR sczLicenseDirectory = NULL;
3640 LPWSTR sczLicenseFilename = NULL;
3641
3642 if (!m_sczLicenseFile || !*m_sczLicenseFile)
3643 {
3644 ExitWithRootFailure(hr, E_INVALIDDATA, "No license file in manifest.");
3645 }
3646
3647 hr = StrAllocString(&sczLicenseFormatted, m_sczLicenseFile, 0);
3648 ExitOnFailure(hr, "Failed to copy manifest license file.");
3649
3650 hr = LocLocalizeString(m_pWixLoc, &sczLicenseFormatted);
3651 ExitOnFailure(hr, "Failed to localize manifest license file.");
3652
3653 hr = BalFormatString(sczLicenseFormatted, &sczLicenseFormatted);
3654 ExitOnFailure(hr, "Failed to expand localized manifest license file.");
3655
3656 hr = PathRelativeToModule(&sczLicensePath, sczLicenseFormatted, m_hModule);
3657 ExitOnFailure(hr, "Failed to get relative path for license file.");
3658
3659 hr = PathGetDirectory(sczLicensePath, &sczLicenseDirectory);
3660 ExitOnFailure(hr, "Failed to get license file directory.");
3661
3662 hr = StrAllocString(&sczLicenseFilename, PathFile(sczLicenseFormatted), 0);
3663 ExitOnFailure(hr, "Failed to copy license file name.");
3664
3665 hr = LocProbeForFile(sczLicenseDirectory, sczLicenseFilename, m_sczLanguage, &sczLicensePath);
3666 ExitOnFailure(hr, "Failed to probe for localized license file.");
3667
3668 hr = ThemeLoadRichEditFromFile(pThemeControl, sczLicensePath, m_hModule);
3669 ExitOnFailure(hr, "Failed to load license file into richedit control.");
3670
3671 LExit:
3672 if (FAILED(hr))
3673 {
3674 BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Failed to load file into license richedit control from path '%ls' manifest value: %ls", sczLicensePath, m_sczLicenseFile);
3675 }
3676
3677 ReleaseStr(sczLicenseFilename);
3678 ReleaseStr(sczLicenseDirectory);
3679 ReleaseStr(sczLicensePath);
3680 ReleaseStr(sczLicenseFormatted);
3681
3682 return hr;
3683 }
3684
3685
3686 //
3687 // OnShowFailure - display the failure page.
3688 //
3689 void OnShowFailure()
3690 {
3691 SetState(WIXSTDBA_STATE_FAILED, S_OK);
3692
3693 // If the UI should be visible, display it now and hide the splash screen
3694 if (BOOTSTRAPPER_DISPLAY_NONE < m_command.display)
3695 {
3696 ::ShowWindow(m_pTheme->hwndParent, SW_SHOW);
3697 }
3698
3699 m_pEngine->CloseSplashScreen();
3700 }
3701
3702
3703 //
3704 // OnShowHelp - display the help page.
3705 //
3706 void OnShowHelp()
3707 {
3708 SetState(WIXSTDBA_STATE_HELP, S_OK);
3709
3710 // If the UI should be visible, display it now and hide the splash screen
3711 if (BOOTSTRAPPER_DISPLAY_NONE < m_command.display)
3712 {
3713 ::ShowWindow(m_pTheme->hwndParent, SW_SHOW);
3714 }
3715
3716 m_pEngine->CloseSplashScreen();
3717 }
3718
3719
3720 //
3721 // OnDetect - start the processing of packages.
3722 //
3723 void OnDetect()
3724 {
3725 HRESULT hr = S_OK;
3726
3727 SetState(WIXSTDBA_STATE_DETECTING, hr);
3728
3729 // Tell the core we're ready for the packages to be processed now.
3730 hr = m_pEngine->Detect();
3731 BalExitOnFailure(hr, "Failed to start detecting chain.");
3732
3733 LExit:
3734 if (FAILED(hr))
3735 {
3736 SetState(WIXSTDBA_STATE_DETECTING, hr);
3737 }
3738 }
3739
3740
3741 //
3742 // OnPlan - plan the detected changes.
3743 //
3744 void OnPlan(
3745 __in BOOTSTRAPPER_ACTION action
3746 )
3747 {
3748 HRESULT hr = S_OK;
3749
3750 m_plannedAction = action;
3751
3752 SetState(WIXSTDBA_STATE_PLANNING, hr);
3753
3754 hr = m_pEngine->Plan(action);
3755 BalExitOnFailure(hr, "Failed to start planning packages.");
3756
3757 LExit:
3758 if (FAILED(hr))
3759 {
3760 SetState(WIXSTDBA_STATE_PLANNING, hr);
3761 }
3762 }
3763
3764
3765 //
3766 // OnPlanPrereqs - preplan the packages to see if the preqba can be skipped.
3767 //
3768 void OnPlanPrereqs(
3769 __in BOOTSTRAPPER_ACTION action
3770 )
3771 {
3772 HRESULT hr = S_OK;
3773
3774 m_plannedAction = action;
3775
3776 SetState(WIXSTDBA_STATE_PLANNING_PREREQS, hr);
3777
3778 hr = m_pEngine->Plan(action);
3779 BalExitOnFailure(hr, "Failed to start planning prereq packages.");
3780
3781 LExit:
3782 if (FAILED(hr))
3783 {
3784 SetState(WIXSTDBA_STATE_PLANNING_PREREQS, hr);
3785 }
3786 }
3787
3788
3789 //
3790 // OnApply - apply the packages.
3791 //
3792 void OnApply()
3793 {
3794 HRESULT hr = S_OK;
3795
3796 SetState(WIXSTDBA_STATE_APPLYING, hr);
3797 SetProgressState(hr);
3798 SetTaskbarButtonProgress(0);
3799
3800 hr = m_pEngine->Apply(m_hWnd);
3801 BalExitOnFailure(hr, "Failed to start applying packages.");
3802
3803 ThemeControlEnable(m_pControlProgressCancelButton, TRUE); // ensure the cancel button is enabled before starting.
3804
3805 LExit:
3806 if (FAILED(hr))
3807 {
3808 SetState(WIXSTDBA_STATE_APPLYING, hr);
3809 }
3810 }
3811
3812
3813 //
3814 // OnChangeState - change state.
3815 //
3816 void OnChangeState(
3817 __in WIXSTDBA_STATE state
3818 )
3819 {
3820 WIXSTDBA_STATE stateOld = m_state;
3821 DWORD dwOldPageId = 0;
3822 DWORD dwNewPageId = 0;
3823 LPWSTR sczText = NULL;
3824 LPWSTR sczUnformattedText = NULL;
3825 LPWSTR sczControlState = NULL;
3826 LPWSTR sczControlName = NULL;
3827
3828 m_state = state;
3829
3830 // If our install is at the end (success or failure) and we're not showing full UI or not updating or
3831 // we successfully installed the prerequisite(s) and either no restart is required or can automatically restart
3832 // then exit.
3833 if ((WIXSTDBA_STATE_APPLIED <= m_state && (BOOTSTRAPPER_DISPLAY_FULL > m_command.display || BOOTSTRAPPER_ACTION_UPDATE_REPLACE == m_plannedAction)) ||
3834 (WIXSTDBA_STATE_APPLIED == m_state && m_fPrereq && (!m_fRestartRequired || m_fShouldRestart && m_fAllowRestart)))
3835 {
3836 // Quietly exit.
3837 ::PostMessageW(m_hWnd, WM_CLOSE, 0, 0);
3838 }
3839 else // try to change the pages.
3840 {
3841 DeterminePageId(stateOld, &dwOldPageId);
3842 DeterminePageId(m_state, &dwNewPageId);
3843
3844 if (dwOldPageId != dwNewPageId)
3845 {
3846 LONGLONG llCanRestart = 0;
3847 LONGLONG llElevated = 0;
3848
3849 BalGetNumericVariable(WIXBUNDLE_VARIABLE_CANRESTART, &llCanRestart);
3850 BalGetNumericVariable(WIXBUNDLE_VARIABLE_ELEVATED, &llElevated);
3851 m_fRestartRequiresElevation = !llCanRestart && !llElevated;
3852
3853 // Enable disable controls per-page.
3854 if (m_rgdwPageIds[WIXSTDBA_PAGE_INSTALL] == dwNewPageId) // on the "Install" page, ensure the install button is enabled/disabled correctly.
3855 {
3856 ThemeControlElevates(m_pControlInstallButton, (m_Bundle.fPerMachine && !llElevated));
3857
3858 // If the EULA control exists, show it only if a license URL is provided as well.
3859 if (m_pControlEulaHyperlink)
3860 {
3861 BOOL fEulaLink = (m_sczLicenseUrl && *m_sczLicenseUrl);
3862 ThemeControlEnable(m_pControlEulaHyperlink, fEulaLink);
3863 ThemeControlEnable(m_pControlEulaAcceptCheckbox, fEulaLink);
3864 }
3865
3866 BOOL fAcceptedLicense = !m_pControlEulaAcceptCheckbox || !ThemeControlEnabled(m_pControlEulaAcceptCheckbox) || ThemeIsControlChecked(m_pControlEulaAcceptCheckbox);
3867 ThemeControlEnable(m_pControlInstallButton, fAcceptedLicense);
3868 }
3869 else if (m_rgdwPageIds[WIXSTDBA_PAGE_MODIFY] == dwNewPageId)
3870 {
3871 ThemeControlElevates(m_pControlRepairButton, (m_Bundle.fPerMachine && !llElevated));
3872 ThemeControlElevates(m_pControlUninstallButton, (m_Bundle.fPerMachine && !llElevated));
3873
3874 ThemeControlEnable(m_pControlRepairButton, !m_fSuppressRepair);
3875 }
3876 else if (m_rgdwPageIds[WIXSTDBA_PAGE_SUCCESS] == dwNewPageId) // on the "Success" page, check if the restart or launch button should be enabled.
3877 {
3878 BOOL fEnableRestartButton = FALSE;
3879 BOOL fLaunchTargetExists = FALSE;
3880
3881 ThemeControlElevates(m_pControlSuccessRestartButton, m_fRestartRequiresElevation);
3882
3883 if (m_fShouldRestart)
3884 {
3885 if (BAL_INFO_RESTART_PROMPT == m_BalInfoCommand.restart)
3886 {
3887 fEnableRestartButton = TRUE;
3888 }
3889 }
3890 else if (m_pControlLaunchButton)
3891 {
3892 fLaunchTargetExists = BalVariableExists(WIXSTDBA_VARIABLE_LAUNCH_TARGET_PATH);
3893 }
3894
3895 ThemeControlEnable(m_pControlLaunchButton, fLaunchTargetExists && BOOTSTRAPPER_ACTION_UNINSTALL < m_plannedAction);
3896 ThemeControlEnable(m_pControlSuccessRestartButton, fEnableRestartButton);
3897 }
3898 else if (m_rgdwPageIds[WIXSTDBA_PAGE_FAILURE] == dwNewPageId) // on the "Failure" page, show error message and check if the restart button should be enabled.
3899 {
3900 BOOL fShowLogLink = (m_Bundle.sczLogVariable && *m_Bundle.sczLogVariable); // if there is a log file variable then we'll assume the log file exists.
3901 BOOL fShowErrorMessage = FALSE;
3902 BOOL fEnableRestartButton = FALSE;
3903
3904 ThemeControlElevates(m_pControlFailureRestartButton, m_fRestartRequiresElevation);
3905
3906 if (FAILED(m_hrFinal))
3907 {
3908 // If we know the failure message, use that.
3909 if (m_sczFailedMessage && *m_sczFailedMessage)
3910 {
3911 StrAllocString(&sczUnformattedText, m_sczFailedMessage, 0);
3912 }
3913 else if (E_MBAHOST_NET452_ON_WIN7RTM == m_hrFinal)
3914 {
3915 HRESULT hr = StrAllocString(&sczUnformattedText, L"#(loc.NET452WIN7RTMErrorMessage)", 0);
3916 if (FAILED(hr))
3917 {
3918 BalLogError(hr, "Failed to initialize NET452WIN7RTMErrorMessage loc identifier.");
3919 }
3920 else
3921 {
3922 hr = LocLocalizeString(m_pWixLoc, &sczUnformattedText);
3923 if (FAILED(hr))
3924 {
3925 BalLogError(hr, "Failed to localize NET452WIN7RTMErrorMessage: %ls", sczUnformattedText);
3926 ReleaseNullStr(sczUnformattedText);
3927 }
3928 }
3929 }
3930 else if (E_DNCHOST_SCD_RUNTIME_FAILURE == m_hrFinal)
3931 {
3932 HRESULT hr = StrAllocString(&sczUnformattedText, L"#(loc.SCDRUNTIMEFAILUREErrorMessage)", 0);
3933 if (FAILED(hr))
3934 {
3935 BalLogError(hr, "Failed to initialize SCDRUNTIMEFAILUREErrorMessage loc identifier.");
3936 }
3937 else
3938 {
3939 hr = LocLocalizeString(m_pWixLoc, &sczUnformattedText);
3940 if (FAILED(hr))
3941 {
3942 BalLogError(hr, "Failed to localize SCDRUNTIMEFAILUREErrorMessage: %ls", sczUnformattedText);
3943 ReleaseNullStr(sczUnformattedText);
3944 }
3945 }
3946 }
3947 else if (E_PREREQBA_INFINITE_LOOP == m_hrFinal)
3948 {
3949 HRESULT hr = StrAllocString(&sczUnformattedText, L"#(loc.PREREQBAINFINITELOOPErrorMessage)", 0);
3950 if (FAILED(hr))
3951 {
3952 BalLogError(hr, "Failed to initialize PREREQBAINFINITELOOPErrorMessage loc identifier.");
3953 }
3954 else
3955 {
3956 hr = LocLocalizeString(m_pWixLoc, &sczUnformattedText);
3957 if (FAILED(hr))
3958 {
3959 BalLogError(hr, "Failed to localize PREREQBAINFINITELOOPErrorMessage: %ls", sczUnformattedText);
3960 ReleaseNullStr(sczUnformattedText);
3961 }
3962 }
3963 }
3964 else // try to get the error message from the error code.
3965 {
3966 StrAllocFromError(&sczUnformattedText, m_hrFinal, NULL);
3967 if (!sczUnformattedText || !*sczUnformattedText)
3968 {
3969 StrAllocFromError(&sczUnformattedText, E_FAIL, NULL);
3970 }
3971 }
3972
3973 if (E_WIXSTDBA_CONDITION_FAILED == m_hrFinal)
3974 {
3975 if (sczUnformattedText)
3976 {
3977 StrAllocString(&sczText, sczUnformattedText, 0);
3978 }
3979 }
3980 else if (E_MBAHOST_NET452_ON_WIN7RTM == m_hrFinal ||
3981 E_DNCHOST_SCD_RUNTIME_FAILURE == m_hrFinal ||
3982 E_PREREQBA_INFINITE_LOOP == m_hrFinal)
3983 {
3984 if (sczUnformattedText)
3985 {
3986 BalFormatString(sczUnformattedText, &sczText);
3987 }
3988 }
3989 else
3990 {
3991 StrAllocFormatted(&sczText, L"0x%08x - %ls", m_hrFinal, sczUnformattedText);
3992 }
3993
3994 ThemeSetTextControl(m_pControlFailureMessageText, sczText);
3995 fShowErrorMessage = TRUE;
3996 }
3997
3998 if (m_fShouldRestart)
3999 {
4000 if (BAL_INFO_RESTART_PROMPT == m_BalInfoCommand.restart)
4001 {
4002 fEnableRestartButton = TRUE;
4003 }
4004 }
4005
4006 ThemeControlEnable(m_pControlFailureLogFileLink, fShowLogLink);
4007 ThemeControlEnable(m_pControlFailureMessageText, fShowErrorMessage);
4008 ThemeControlEnable(m_pControlFailureRestartButton, fEnableRestartButton);
4009 }
4010
4011 HRESULT hr = ThemeShowPage(m_pTheme, dwOldPageId, SW_HIDE);
4012 if (FAILED(hr))
4013 {
4014 BalLogError(hr, "Failed to hide page: %u", dwOldPageId);
4015 }
4016
4017 hr = ThemeShowPage(m_pTheme, dwNewPageId, SW_SHOW);
4018 if (FAILED(hr))
4019 {
4020 BalLogError(hr, "Failed to show page: %u", dwNewPageId);
4021 }
4022
4023 // On the install page set the focus to the install button or the next enabled control if install is disabled.
4024 if (m_rgdwPageIds[WIXSTDBA_PAGE_INSTALL] == dwNewPageId)
4025 {
4026 ThemeSetFocus(m_pControlInstallButton);
4027 }
4028 }
4029 }
4030
4031 ReleaseStr(sczText);
4032 ReleaseStr(sczUnformattedText);
4033 ReleaseStr(sczControlState);
4034 ReleaseStr(sczControlName);
4035 }
4036
4037
4038 //
4039 // OnClose - called when the window is trying to be closed.
4040 //
4041 BOOL OnClose()
4042 {
4043 BOOL fClose = FALSE;
4044 BOOL fCancel = FALSE;
4045
4046 // If we've already succeeded or failed or showing the help page, just close (prompts are annoying if the bootstrapper is done).
4047 if (WIXSTDBA_STATE_APPLIED <= m_state || WIXSTDBA_STATE_HELP == m_state)
4048 {
4049 fClose = TRUE;
4050 }
4051 else // prompt the user or force the cancel if there is no UI.
4052 {
4053 ::EnterCriticalSection(&m_csShowingInternalUiThisPackage);
4054 fClose = PromptCancel(
4055 m_hWnd,
4056 BOOTSTRAPPER_DISPLAY_FULL != m_command.display || m_fShowingInternalUiThisPackage,
4057 m_sczConfirmCloseMessage ? m_sczConfirmCloseMessage : L"Are you sure you want to cancel?",
4058 m_pTheme->sczCaption);
4059 ::LeaveCriticalSection(&m_csShowingInternalUiThisPackage);
4060
4061 fCancel = fClose;
4062 }
4063
4064 // If we're doing progress then we never close, we just cancel to let rollback occur.
4065 if (WIXSTDBA_STATE_APPLYING <= m_state && WIXSTDBA_STATE_APPLIED > m_state)
4066 {
4067 // If we canceled, disable cancel button since clicking it again is silly.
4068 if (fClose)
4069 {
4070 ThemeControlEnable(m_pControlProgressCancelButton, FALSE);
4071 }
4072
4073 fClose = FALSE;
4074 }
4075
4076 if (fClose)
4077 {
4078 DWORD dwCurrentPageId = 0;
4079 DeterminePageId(m_state, &dwCurrentPageId);
4080
4081 // Hide the current page to let thmutil do its thing with variables.
4082 ThemeShowPageEx(m_pTheme, dwCurrentPageId, SW_HIDE, fCancel ? THEME_SHOW_PAGE_REASON_CANCEL : THEME_SHOW_PAGE_REASON_DEFAULT);
4083 }
4084
4085 return fClose;
4086 }
4087
4088
4089 //
4090 // OnClickAcceptCheckbox - allow the install to continue.
4091 //
4092 void OnClickAcceptCheckbox()
4093 {
4094 BOOL fAcceptedLicense = ThemeIsControlChecked(m_pControlEulaAcceptCheckbox);
4095 ThemeControlEnable(m_pControlInstallButton, fAcceptedLicense);
4096 }
4097
4098
4099 //
4100 // OnClickInstallButton - start the install by planning the packages.
4101 //
4102 void OnClickInstallButton()
4103 {
4104 this->OnPlan(BOOTSTRAPPER_ACTION_INSTALL);
4105 }
4106
4107
4108 //
4109 // OnClickRepairButton - start the repair.
4110 //
4111 void OnClickRepairButton()
4112 {
4113 this->OnPlan(BOOTSTRAPPER_ACTION_REPAIR);
4114 }
4115
4116
4117 //
4118 // OnClickUninstallButton - start the uninstall.
4119 //
4120 void OnClickUninstallButton()
4121 {
4122 this->OnPlan(BOOTSTRAPPER_ACTION_UNINSTALL);
4123 }
4124
4125
4126 //
4127 // OnClickUpdateButton - start the update process.
4128 //
4129 void OnClickUpdateButton()
4130 {
4131 this->OnPlan(BOOTSTRAPPER_ACTION_UPDATE_REPLACE);
4132 }
4133
4134
4135 //
4136 // OnClickCloseButton - close the application.
4137 //
4138 void OnClickCloseButton()
4139 {
4140 ::SendMessageW(m_hWnd, WM_CLOSE, 0, 0);
4141 }
4142
4143
4144 //
4145 // OnClickEulaLink - show the end user license agreement.
4146 //
4147 void OnClickEulaLink()
4148 {
4149 HRESULT hr = S_OK;
4150 LPWSTR sczLicenseUrl = NULL;
4151 LPWSTR sczLicensePath = NULL;
4152 LPWSTR sczLicenseDirectory = NULL;
4153 LPWSTR sczLicenseFilename = NULL;
4154 URI_PROTOCOL protocol = URI_PROTOCOL_UNKNOWN;
4155
4156 hr = StrAllocString(&sczLicenseUrl, m_sczLicenseUrl, 0);
4157 BalExitOnFailure(hr, "Failed to copy license URL: %ls", m_sczLicenseUrl);
4158
4159 hr = LocLocalizeString(m_pWixLoc, &sczLicenseUrl);
4160 BalExitOnFailure(hr, "Failed to localize license URL: %ls", m_sczLicenseUrl);
4161
4162 // Assume there is no hidden variables to be formatted
4163 // so don't worry about securely freeing it.
4164 hr = BalFormatString(sczLicenseUrl, &sczLicenseUrl);
4165 BalExitOnFailure(hr, "Failed to get formatted license URL: %ls", m_sczLicenseUrl);
4166
4167 hr = UriProtocol(sczLicenseUrl, &protocol);
4168 if (FAILED(hr) || URI_PROTOCOL_UNKNOWN == protocol)
4169 {
4170 // Probe for localized license file
4171 hr = PathRelativeToModule(&sczLicensePath, sczLicenseUrl, m_hModule);
4172 if (SUCCEEDED(hr))
4173 {
4174 hr = PathGetDirectory(sczLicensePath, &sczLicenseDirectory);
4175 if (SUCCEEDED(hr))
4176 {
4177 hr = LocProbeForFile(sczLicenseDirectory, PathFile(sczLicenseUrl), m_sczLanguage, &sczLicensePath);
4178 }
4179 }
4180 }
4181
4182 hr = ShelExecUnelevated(sczLicensePath ? sczLicensePath : sczLicenseUrl, NULL, L"open", NULL, SW_SHOWDEFAULT);
4183 BalExitOnFailure(hr, "Failed to launch URL to EULA.");
4184
4185 LExit:
4186 ReleaseStr(sczLicensePath);
4187 ReleaseStr(sczLicenseUrl);
4188 ReleaseStr(sczLicenseDirectory);
4189 ReleaseStr(sczLicenseFilename);
4190 }
4191
4192
4193 //
4194 // OnClickLaunchButton - launch the app from the success page.
4195 //
4196 void OnClickLaunchButton()
4197 {
4198 HRESULT hr = S_OK;
4199 LPWSTR sczUnformattedLaunchTarget = NULL;
4200 LPWSTR sczLaunchTarget = NULL;
4201 LPWSTR sczLaunchTargetElevatedId = NULL;
4202 LPWSTR sczUnformattedArguments = NULL;
4203 LPWSTR sczArguments = NULL;
4204 LPWSTR sczUnformattedLaunchFolder = NULL;
4205 LPWSTR sczLaunchFolder = NULL;
4206 int nCmdShow = SW_SHOWNORMAL;
4207
4208 hr = BalGetStringVariable(WIXSTDBA_VARIABLE_LAUNCH_TARGET_PATH, &sczUnformattedLaunchTarget);
4209 BalExitOnFailure(hr, "Failed to get launch target variable '%ls'.", WIXSTDBA_VARIABLE_LAUNCH_TARGET_PATH);
4210
4211 hr = BalFormatString(sczUnformattedLaunchTarget, &sczLaunchTarget);
4212 BalExitOnFailure(hr, "Failed to format launch target variable: %ls", sczUnformattedLaunchTarget);
4213
4214 if (BalVariableExists(WIXSTDBA_VARIABLE_LAUNCH_TARGET_ELEVATED_ID))
4215 {
4216 hr = BalGetStringVariable(WIXSTDBA_VARIABLE_LAUNCH_TARGET_ELEVATED_ID, &sczLaunchTargetElevatedId);
4217 BalExitOnFailure(hr, "Failed to get launch target elevated id '%ls'.", WIXSTDBA_VARIABLE_LAUNCH_TARGET_ELEVATED_ID);
4218 }
4219
4220 if (BalVariableExists(WIXSTDBA_VARIABLE_LAUNCH_ARGUMENTS))
4221 {
4222 hr = BalGetStringVariable(WIXSTDBA_VARIABLE_LAUNCH_ARGUMENTS, &sczUnformattedArguments);
4223 BalExitOnFailure(hr, "Failed to get launch arguments '%ls'.", WIXSTDBA_VARIABLE_LAUNCH_ARGUMENTS);
4224 }
4225
4226 if (BalVariableExists(WIXSTDBA_VARIABLE_LAUNCH_HIDDEN))
4227 {
4228 nCmdShow = SW_HIDE;
4229 }
4230
4231 if (BalVariableExists(WIXSTDBA_VARIABLE_LAUNCH_WORK_FOLDER))
4232 {
4233 hr = BalGetStringVariable(WIXSTDBA_VARIABLE_LAUNCH_WORK_FOLDER, &sczUnformattedLaunchFolder);
4234 BalExitOnFailure(hr, "Failed to get launch working directory variable '%ls'.", WIXSTDBA_VARIABLE_LAUNCH_WORK_FOLDER);
4235 }
4236
4237 if (sczLaunchTargetElevatedId && !m_fTriedToLaunchElevated)
4238 {
4239 m_fTriedToLaunchElevated = TRUE;
4240 hr = m_pEngine->LaunchApprovedExe(m_hWnd, sczLaunchTargetElevatedId, sczUnformattedArguments, 0);
4241 if (FAILED(hr))
4242 {
4243 BalLogError(hr, "Failed to launch elevated target: %ls", sczLaunchTargetElevatedId);
4244
4245 //try with ShelExec next time
4246 OnClickLaunchButton();
4247 }
4248 }
4249 else
4250 {
4251 if (sczUnformattedArguments)
4252 {
4253 hr = BalFormatString(sczUnformattedArguments, &sczArguments);
4254 BalExitOnFailure(hr, "Failed to format launch arguments variable: %ls", sczUnformattedArguments);
4255 }
4256
4257 if (sczUnformattedLaunchFolder)
4258 {
4259 hr = BalFormatString(sczUnformattedLaunchFolder, &sczLaunchFolder);
4260 BalExitOnFailure(hr, "Failed to format launch working directory variable: %ls", sczUnformattedLaunchFolder);
4261 }
4262
4263 hr = ShelExec(sczLaunchTarget, sczArguments, L"open", sczLaunchFolder, nCmdShow, m_hWnd, NULL);
4264 BalExitOnFailure(hr, "Failed to launch target: %ls", sczLaunchTarget);
4265
4266 ::PostMessageW(m_hWnd, WM_CLOSE, 0, 0);
4267 }
4268
4269 LExit:
4270 StrSecureZeroFreeString(sczLaunchFolder);
4271 ReleaseStr(sczUnformattedLaunchFolder);
4272 StrSecureZeroFreeString(sczArguments);
4273 ReleaseStr(sczUnformattedArguments);
4274 ReleaseStr(sczLaunchTargetElevatedId);
4275 StrSecureZeroFreeString(sczLaunchTarget);
4276 ReleaseStr(sczUnformattedLaunchTarget);
4277 }
4278
4279
4280 //
4281 // OnClickRestartButton - allows the restart and closes the app.
4282 //
4283 void OnClickRestartButton()
4284 {
4285 AssertSz(m_fRestartRequired, "Restart must be requested to be able to click on the restart button.");
4286
4287 if (m_fRestartRequiresElevation)
4288 {
4289 m_fElevatingForRestart = TRUE;
4290 ThemeControlEnable(m_pControlFailureRestartButton, FALSE);
4291 ThemeControlEnable(m_pControlSuccessRestartButton, FALSE);
4292
4293 m_pEngine->Elevate(m_hWnd);
4294 }
4295 else
4296 {
4297 m_fAllowRestart = TRUE;
4298
4299 ::SendMessageW(m_hWnd, WM_CLOSE, 0, 0);
4300 }
4301 }
4302
4303
4304 //
4305 // OnClickLogFileLink - show the log file.
4306 //
4307 void OnClickLogFileLink()
4308 {
4309 HRESULT hr = S_OK;
4310 LPWSTR sczLogFile = NULL;
4311
4312 hr = BalGetStringVariable(m_Bundle.sczLogVariable, &sczLogFile);
4313 BalExitOnFailure(hr, "Failed to get log file variable '%ls'.", m_Bundle.sczLogVariable);
4314
4315 hr = ShelExecUnelevated(L"notepad.exe", sczLogFile, L"open", NULL, SW_SHOWDEFAULT);
4316 BalExitOnFailure(hr, "Failed to open log file target: %ls", sczLogFile);
4317
4318 LExit:
4319 ReleaseStr(sczLogFile);
4320 }
4321
4322 BOOL OnThemeControlWmCommand(
4323 __in const THEME_CONTROLWMCOMMAND_ARGS* pArgs,
4324 __in THEME_CONTROLWMCOMMAND_RESULTS* pResults
4325 )
4326 {
4327 HRESULT hr = S_OK;
4328 BOOL fProcessed = FALSE;
4329 BA_FUNCTIONS_ONTHEMECONTROLWMCOMMAND_ARGS themeControlWmCommandArgs = { };
4330 BA_FUNCTIONS_ONTHEMECONTROLWMCOMMAND_RESULTS themeControlWmCommandResults = { };
4331
4332 switch (HIWORD(pArgs->wParam))
4333 {
4334 case BN_CLICKED:
4335 switch (pArgs->pThemeControl->wId)
4336 {
4337 case WIXSTDBA_CONTROL_EULA_ACCEPT_CHECKBOX:
4338 OnClickAcceptCheckbox();
4339 fProcessed = TRUE;
4340 pResults->lResult = 0;
4341 ExitFunction();
4342
4343 case WIXSTDBA_CONTROL_INSTALL_BUTTON:
4344 OnClickInstallButton();
4345 fProcessed = TRUE;
4346 pResults->lResult = 0;
4347 ExitFunction();
4348
4349 case WIXSTDBA_CONTROL_REPAIR_BUTTON:
4350 OnClickRepairButton();
4351 fProcessed = TRUE;
4352 pResults->lResult = 0;
4353 ExitFunction();
4354
4355 case WIXSTDBA_CONTROL_UNINSTALL_BUTTON:
4356 OnClickUninstallButton();
4357 fProcessed = TRUE;
4358 pResults->lResult = 0;
4359 ExitFunction();
4360
4361 case WIXSTDBA_CONTROL_INSTALL_UPDATE_BUTTON:
4362 case WIXSTDBA_CONTROL_MODIFY_UPDATE_BUTTON:
4363 OnClickUpdateButton();
4364 fProcessed = TRUE;
4365 pResults->lResult = 0;
4366 ExitFunction();
4367
4368 case WIXSTDBA_CONTROL_LAUNCH_BUTTON:
4369 OnClickLaunchButton();
4370 fProcessed = TRUE;
4371 pResults->lResult = 0;
4372 ExitFunction();
4373
4374 case WIXSTDBA_CONTROL_SUCCESS_RESTART_BUTTON: __fallthrough;
4375 case WIXSTDBA_CONTROL_FAILURE_RESTART_BUTTON:
4376 OnClickRestartButton();
4377 fProcessed = TRUE;
4378 pResults->lResult = 0;
4379 ExitFunction();
4380
4381 case WIXSTDBA_CONTROL_PROGRESS_CANCEL_BUTTON:
4382 OnClickCloseButton();
4383 fProcessed = TRUE;
4384 pResults->lResult = 0;
4385 ExitFunction();
4386 }
4387 break;
4388 }
4389
4390 if (m_pfnBAFunctionsProc)
4391 {
4392 themeControlWmCommandArgs.cbSize = sizeof(themeControlWmCommandArgs);
4393 themeControlWmCommandArgs.wParam = pArgs->wParam;
4394 themeControlWmCommandArgs.wzName = pArgs->pThemeControl->sczName;
4395 themeControlWmCommandArgs.wId = pArgs->pThemeControl->wId;
4396 themeControlWmCommandArgs.hWnd = pArgs->pThemeControl->hWnd;
4397
4398 themeControlWmCommandResults.cbSize = sizeof(themeControlWmCommandResults);
4399 themeControlWmCommandResults.lResult = pResults->lResult;
4400
4401 hr = m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONTHEMECONTROLWMCOMMAND, &themeControlWmCommandArgs, &themeControlWmCommandResults, m_pvBAFunctionsProcContext);
4402 if (E_NOTIMPL != hr)
4403 {
4404 BalExitOnFailure(hr, "BAFunctions OnThemeControlWmCommand failed.");
4405
4406 if (themeControlWmCommandResults.fProcessed)
4407 {
4408 fProcessed = TRUE;
4409 pResults->lResult = themeControlWmCommandResults.lResult;
4410 ExitFunction();
4411 }
4412 }
4413 }
4414
4415LExit:
4416 return fProcessed;
4417 }
4418
4419 BOOL OnThemeControlWmNotify(
4420 __in const THEME_CONTROLWMNOTIFY_ARGS* pArgs,
4421 __in THEME_CONTROLWMNOTIFY_RESULTS* pResults
4422 )
4423 {
4424 HRESULT hr = S_OK;
4425 BOOL fProcessed = FALSE;
4426 BA_FUNCTIONS_ONTHEMECONTROLWMNOTIFY_ARGS themeControlWmNotifyArgs = { };
4427 BA_FUNCTIONS_ONTHEMECONTROLWMNOTIFY_RESULTS themeControlWmNotifyResults = { };
4428
4429 switch (pArgs->lParam->code)
4430 {
4431 case NM_CLICK: __fallthrough;
4432 case NM_RETURN:
4433 switch (pArgs->pThemeControl->wId)
4434 {
4435 case WIXSTDBA_CONTROL_EULA_LINK:
4436 OnClickEulaLink();
4437 fProcessed = TRUE;
4438 pResults->lResult = 1;
4439 ExitFunction();
4440 case WIXSTDBA_CONTROL_FAILURE_LOGFILE_LINK:
4441 OnClickLogFileLink();
4442 fProcessed = TRUE;
4443 pResults->lResult = 1;
4444 ExitFunction();
4445 }
4446 }
4447
4448 if (m_pfnBAFunctionsProc)
4449 {
4450 themeControlWmNotifyArgs.cbSize = sizeof(themeControlWmNotifyArgs);
4451 themeControlWmNotifyArgs.lParam = pArgs->lParam;
4452 themeControlWmNotifyArgs.wzName = pArgs->pThemeControl->sczName;
4453 themeControlWmNotifyArgs.wId = pArgs->pThemeControl->wId;
4454 themeControlWmNotifyArgs.hWnd = pArgs->pThemeControl->hWnd;
4455
4456 themeControlWmNotifyResults.cbSize = sizeof(themeControlWmNotifyResults);
4457 themeControlWmNotifyResults.lResult = pResults->lResult;
4458
4459 hr = m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONTHEMECONTROLWMCOMMAND, &themeControlWmNotifyArgs, &themeControlWmNotifyResults, m_pvBAFunctionsProcContext);
4460 if (E_NOTIMPL != hr)
4461 {
4462 BalExitOnFailure(hr, "BAFunctions OnThemeControlWmNotify failed.");
4463
4464 if (themeControlWmNotifyResults.fProcessed)
4465 {
4466 fProcessed = TRUE;
4467 pResults->lResult = themeControlWmNotifyResults.lResult;
4468 ExitFunction();
4469 }
4470 }
4471 }
4472
4473LExit:
4474 return fProcessed;
4475 }
4476
4477
4478 //
4479 // SetState
4480 //
4481 void SetState(
4482 __in WIXSTDBA_STATE state,
4483 __in HRESULT hrStatus
4484 )
4485 {
4486#ifdef DEBUG
4487 BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "WIXSTDBA: SetState() - setting state to %u with status 0x%08x.", state, hrStatus);
4488#endif
4489
4490 if (FAILED(hrStatus))
4491 {
4492 m_hrFinal = hrStatus;
4493 }
4494
4495 if (FAILED(m_hrFinal))
4496 {
4497 state = WIXSTDBA_STATE_FAILED;
4498 }
4499
4500 if (m_state < state)
4501 {
4502 ::PostMessageW(m_hWnd, WM_WIXSTDBA_CHANGE_STATE, 0, state);
4503 }
4504 }
4505
4506
4507 void DeterminePageId(
4508 __in WIXSTDBA_STATE state,
4509 __out DWORD* pdwPageId
4510 )
4511 {
4512 if (BOOTSTRAPPER_DISPLAY_PASSIVE == m_command.display)
4513 {
4514 switch (state)
4515 {
4516 case WIXSTDBA_STATE_INITIALIZED:
4517 *pdwPageId = BOOTSTRAPPER_ACTION_HELP == m_command.action ? m_rgdwPageIds[WIXSTDBA_PAGE_HELP] : m_rgdwPageIds[WIXSTDBA_PAGE_LOADING];
4518 break;
4519
4520 case WIXSTDBA_STATE_HELP:
4521 *pdwPageId = m_rgdwPageIds[WIXSTDBA_PAGE_HELP];
4522 break;
4523
4524 case WIXSTDBA_STATE_DETECTING:
4525 *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];
4526 break;
4527
4528 case WIXSTDBA_STATE_DETECTED: __fallthrough;
4529 case WIXSTDBA_STATE_PLANNING_PREREQS: __fallthrough;
4530 case WIXSTDBA_STATE_PLANNED_PREREQS: __fallthrough;
4531 case WIXSTDBA_STATE_PLANNING: __fallthrough;
4532 case WIXSTDBA_STATE_PLANNED: __fallthrough;
4533 case WIXSTDBA_STATE_APPLYING: __fallthrough;
4534 case WIXSTDBA_STATE_CACHING: __fallthrough;
4535 case WIXSTDBA_STATE_CACHED: __fallthrough;
4536 case WIXSTDBA_STATE_EXECUTING: __fallthrough;
4537 case WIXSTDBA_STATE_EXECUTED:
4538 *pdwPageId = m_rgdwPageIds[WIXSTDBA_PAGE_PROGRESS_PASSIVE] ? m_rgdwPageIds[WIXSTDBA_PAGE_PROGRESS_PASSIVE] : m_rgdwPageIds[WIXSTDBA_PAGE_PROGRESS];
4539 break;
4540
4541 default:
4542 *pdwPageId = 0;
4543 break;
4544 }
4545 }
4546 else if (BOOTSTRAPPER_DISPLAY_FULL == m_command.display)
4547 {
4548 switch (state)
4549 {
4550 case WIXSTDBA_STATE_INITIALIZING:
4551 *pdwPageId = 0;
4552 break;
4553
4554 case WIXSTDBA_STATE_INITIALIZED:
4555 *pdwPageId = BOOTSTRAPPER_ACTION_HELP == m_command.action ? m_rgdwPageIds[WIXSTDBA_PAGE_HELP] : m_rgdwPageIds[WIXSTDBA_PAGE_LOADING];
4556 break;
4557
4558 case WIXSTDBA_STATE_HELP:
4559 *pdwPageId = m_rgdwPageIds[WIXSTDBA_PAGE_HELP];
4560 break;
4561
4562 case WIXSTDBA_STATE_DETECTING:
4563 *pdwPageId = m_rgdwPageIds[WIXSTDBA_PAGE_LOADING];
4564 break;
4565
4566 case WIXSTDBA_STATE_DETECTED:
4567 case WIXSTDBA_STATE_PLANNING_PREREQS: __fallthrough;
4568 case WIXSTDBA_STATE_PLANNED_PREREQS: __fallthrough;
4569 switch (m_command.action)
4570 {
4571 case BOOTSTRAPPER_ACTION_INSTALL:
4572 *pdwPageId = m_rgdwPageIds[WIXSTDBA_PAGE_INSTALL];
4573 break;
4574
4575 case BOOTSTRAPPER_ACTION_MODIFY: __fallthrough;
4576 case BOOTSTRAPPER_ACTION_REPAIR: __fallthrough;
4577 case BOOTSTRAPPER_ACTION_UNINSTALL:
4578 *pdwPageId = m_rgdwPageIds[WIXSTDBA_PAGE_MODIFY];
4579 break;
4580 }
4581 break;
4582
4583 case WIXSTDBA_STATE_PLANNING: __fallthrough;
4584 case WIXSTDBA_STATE_PLANNED: __fallthrough;
4585 case WIXSTDBA_STATE_APPLYING: __fallthrough;
4586 case WIXSTDBA_STATE_CACHING: __fallthrough;
4587 case WIXSTDBA_STATE_CACHED: __fallthrough;
4588 case WIXSTDBA_STATE_EXECUTING: __fallthrough;
4589 case WIXSTDBA_STATE_EXECUTED:
4590 *pdwPageId = m_rgdwPageIds[WIXSTDBA_PAGE_PROGRESS];
4591 break;
4592
4593 case WIXSTDBA_STATE_APPLIED:
4594 *pdwPageId = m_rgdwPageIds[WIXSTDBA_PAGE_SUCCESS];
4595 break;
4596
4597 case WIXSTDBA_STATE_FAILED:
4598 *pdwPageId = m_rgdwPageIds[WIXSTDBA_PAGE_FAILURE];
4599 break;
4600 }
4601 }
4602 }
4603
4604
4605 HRESULT EvaluateConditions()
4606 {
4607 HRESULT hr = S_OK;
4608 BOOL fResult = FALSE;
4609
4610 for (DWORD i = 0; i < m_Conditions.cConditions; ++i)
4611 {
4612 BAL_CONDITION* pCondition = m_Conditions.rgConditions + i;
4613
4614 hr = BalConditionEvaluate(pCondition, m_pEngine, &fResult, &m_sczFailedMessage);
4615 BalExitOnFailure(hr, "Failed to evaluate condition.");
4616
4617 if (!fResult)
4618 {
4619 hr = E_WIXSTDBA_CONDITION_FAILED;
4620 BalExitOnFailure(hr, "%ls", m_sczFailedMessage);
4621 }
4622 }
4623
4624 ReleaseNullStrSecure(m_sczFailedMessage);
4625
4626 LExit:
4627 return hr;
4628 }
4629
4630 void UpdateCacheProgress(
4631 __in DWORD dwOverallPercentage
4632 )
4633 {
4634 WCHAR wzProgress[5] = { };
4635
4636 ::StringCchPrintfW(wzProgress, countof(wzProgress), L"%u%%", dwOverallPercentage);
4637 ThemeSetTextControl(m_pControlCacheProgressText, wzProgress);
4638
4639 ThemeSetProgressControl(m_pControlCacheProgressbar, dwOverallPercentage);
4640
4641 m_dwCalculatedCacheProgress = dwOverallPercentage * WIXSTDBA_ACQUIRE_PERCENTAGE / 100;
4642 ThemeSetProgressControl(m_pControlOverallCalculatedProgressbar, m_dwCalculatedCacheProgress + m_dwCalculatedExecuteProgress);
4643
4644 SetTaskbarButtonProgress(m_dwCalculatedCacheProgress + m_dwCalculatedExecuteProgress);
4645 }
4646
4647
4648 void SetTaskbarButtonProgress(
4649 __in DWORD dwOverallPercentage
4650 )
4651 {
4652 HRESULT hr = S_OK;
4653
4654 if (m_fTaskbarButtonOK)
4655 {
4656 hr = m_pTaskbarList->SetProgressValue(m_hWnd, dwOverallPercentage, 100UL);
4657 BalExitOnFailure(hr, "Failed to set taskbar button progress to: %d%%.", dwOverallPercentage);
4658 }
4659
4660 LExit:
4661 return;
4662 }
4663
4664
4665 void SetTaskbarButtonState(
4666 __in TBPFLAG tbpFlags
4667 )
4668 {
4669 HRESULT hr = S_OK;
4670
4671 if (m_fTaskbarButtonOK)
4672 {
4673 hr = m_pTaskbarList->SetProgressState(m_hWnd, tbpFlags);
4674 BalExitOnFailure(hr, "Failed to set taskbar button state: %d.", tbpFlags);
4675 }
4676
4677 LExit:
4678 return;
4679 }
4680
4681
4682 void SetProgressState(
4683 __in HRESULT hrStatus
4684 )
4685 {
4686 TBPFLAG flag = TBPF_NORMAL;
4687
4688 if (IsCanceled() || HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT) == hrStatus)
4689 {
4690 flag = TBPF_PAUSED;
4691 }
4692 else if (IsRollingBack() || FAILED(hrStatus))
4693 {
4694 flag = TBPF_ERROR;
4695 }
4696
4697 SetTaskbarButtonState(flag);
4698 }
4699
4700
4701 HRESULT LoadBAFunctions(
4702 __in IXMLDOMDocument* pixdManifest
4703 )
4704 {
4705 HRESULT hr = S_OK;
4706 IXMLDOMNode* pBAFunctionsNode = NULL;
4707 LPWSTR sczBafName = NULL;
4708 LPWSTR sczBafPath = NULL;
4709 BA_FUNCTIONS_CREATE_ARGS bafCreateArgs = { };
4710 BA_FUNCTIONS_CREATE_RESULTS bafCreateResults = { };
4711 BOOL fXmlFound = FALSE;
4712
4713 hr = XmlSelectSingleNode(pixdManifest, L"/BootstrapperApplicationData/WixBalBAFunctions", &pBAFunctionsNode);
4714 BalExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to read WixBalBAFunctions node from BootstrapperApplicationData.xml.");
4715
4716 if (!fXmlFound)
4717 {
4718 ExitFunction();
4719 }
4720
4721 hr = XmlGetAttributeEx(pBAFunctionsNode, L"FilePath", &sczBafName);
4722 BalExitOnRequiredXmlQueryFailure(hr, "Failed to get BAFunctions FilePath.");
4723
4724 hr = PathRelativeToModule(&sczBafPath, sczBafName, m_hModule);
4725 BalExitOnFailure(hr, "Failed to get path to BAFunctions DLL.");
4726
4727 BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "WIXSTDBA: LoadBAFunctions() - BAFunctions DLL %ls", sczBafPath);
4728
4729 m_hBAFModule = ::LoadLibraryExW(sczBafPath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
4730 BalExitOnNullWithLastError(m_hBAFModule, hr, "WIXSTDBA: LoadBAFunctions() - Failed to load DLL %ls", sczBafPath);
4731
4732 PFN_BA_FUNCTIONS_CREATE pfnBAFunctionsCreate = reinterpret_cast<PFN_BA_FUNCTIONS_CREATE>(::GetProcAddress(m_hBAFModule, "BAFunctionsCreate"));
4733 BalExitOnNullWithLastError(pfnBAFunctionsCreate, hr, "Failed to get BAFunctionsCreate entry-point from: %ls", sczBafPath);
4734
4735 bafCreateArgs.cbSize = sizeof(bafCreateArgs);
4736 bafCreateArgs.qwBAFunctionsAPIVersion = MAKEQWORDVERSION(2021, 11, 8, 0);
4737 bafCreateArgs.pBootstrapperCreateArgs = &m_createArgs;
4738
4739 bafCreateResults.cbSize = sizeof(bafCreateResults);
4740
4741 hr = pfnBAFunctionsCreate(&bafCreateArgs, &bafCreateResults);
4742 BalExitOnFailure(hr, "Failed to create BAFunctions.");
4743
4744 m_pfnBAFunctionsProc = bafCreateResults.pfnBAFunctionsProc;
4745 m_pvBAFunctionsProcContext = bafCreateResults.pvBAFunctionsProcContext;
4746
4747 LExit:
4748 if (m_hBAFModule && !m_pfnBAFunctionsProc)
4749 {
4750 ::FreeLibrary(m_hBAFModule);
4751 m_hBAFModule = NULL;
4752 }
4753 ReleaseStr(sczBafPath);
4754 ReleaseStr(sczBafName);
4755 ReleaseObject(pBAFunctionsNode);
4756
4757 return hr;
4758 }
4759
4760
4761public:
4762 //
4763 // Constructor - initialize member variables.
4764 //
4765 CWixStandardBootstrapperApplication(
4766 __in HMODULE hModule,
4767 __in_opt PREQBA_DATA* pPrereqData,
4768 __in IBootstrapperEngine* pEngine
4769 ) : CBalBaseBootstrapperApplication(pEngine, 3, 3000)
4770 {
4771 THEME_ASSIGN_CONTROL_ID* pAssignControl = NULL;
4772 DWORD dwAutomaticBehaviorType = THEME_CONTROL_AUTOMATIC_BEHAVIOR_EXCLUDE_ENABLED | THEME_CONTROL_AUTOMATIC_BEHAVIOR_EXCLUDE_VISIBLE | THEME_CONTROL_AUTOMATIC_BEHAVIOR_EXCLUDE_ACTION | THEME_CONTROL_AUTOMATIC_BEHAVIOR_EXCLUDE_VALUE;
4773
4774 m_hModule = hModule;
4775 m_command = { };
4776 m_createArgs = { };
4777
4778 m_plannedAction = BOOTSTRAPPER_ACTION_UNKNOWN;
4779
4780 m_sczAfterForcedRestartPackage = NULL;
4781 m_sczBundleVersion = NULL;
4782
4783 m_pWixLoc = NULL;
4784 m_Bundle = { };
4785 m_Conditions = { };
4786 m_sczConfirmCloseMessage = NULL;
4787 m_sczFailedMessage = NULL;
4788
4789 m_sczLanguage = NULL;
4790 m_pTheme = NULL;
4791 memset(m_rgdwPageIds, 0, sizeof(m_rgdwPageIds));
4792 m_hUiThread = NULL;
4793 m_fRegistered = FALSE;
4794 m_hWnd = NULL;
4795
4796 m_state = WIXSTDBA_STATE_INITIALIZING;
4797 m_hrFinal = pPrereqData ? pPrereqData->hrFatalError : S_OK;
4798
4799 m_restartResult = BOOTSTRAPPER_APPLY_RESTART_NONE;
4800 m_fRestartRequired = FALSE;
4801 m_fShouldRestart = FALSE;
4802 m_fAllowRestart = FALSE;
4803 m_fRestartRequiresElevation = FALSE;
4804 m_fElevatingForRestart = FALSE;
4805
4806 m_sczLicenseFile = NULL;
4807 m_sczLicenseUrl = NULL;
4808 m_fSuppressDowngradeFailure = FALSE;
4809 m_fDowngrading = FALSE;
4810 m_fSuppressRepair = FALSE;
4811 m_fSupportCacheOnly = FALSE;
4812 m_fRequestedCacheOnly = FALSE;
4813
4814 m_pTaskbarList = NULL;
4815 m_uTaskbarButtonCreatedMessage = UINT_MAX;
4816 m_fTaskbarButtonOK = FALSE;
4817 ::InitializeCriticalSection(&m_csShowingInternalUiThisPackage);
4818 m_fShowingInternalUiThisPackage = FALSE;
4819 m_fTriedToLaunchElevated = FALSE;
4820
4821 m_pPrereqData = pPrereqData;
4822 m_fPrereq = NULL != pPrereqData;
4823 m_fPreplanPrereqs = FALSE;
4824 m_fPerformHelp = !m_fPrereq || m_pPrereqData->fPerformHelp;
4825 m_fPrereqPackagePlanned = FALSE;
4826 m_fPrereqInstalled = FALSE;
4827 m_fPrereqSkipped = FALSE;
4828
4829 m_fShowStandardFilesInUse = FALSE;
4830 m_fShowRMFilesInUse = FALSE;
4831 m_fShowNetfxFilesInUse = FALSE;
4832 m_nLastMsiFilesInUseResult = IDNOACTION;
4833 m_nLastNetfxFilesInUseResult = IDNOACTION;
4834 m_pFilesInUseTitleLoc = NULL;
4835 m_pFilesInUseLabelLoc = NULL;
4836 m_pFilesInUseCloseRadioButtonLoc = NULL;
4837 m_pFilesInUseNetfxCloseRadioButtonLoc = NULL;
4838 m_pFilesInUseDontCloseRadioButtonLoc = NULL;
4839 m_pFilesInUseRetryButtonLoc = NULL;
4840 m_pFilesInUseIgnoreButtonLoc = NULL;
4841 m_pFilesInUseExitButtonLoc = NULL;
4842
4843 pEngine->AddRef();
4844 m_pEngine = pEngine;
4845
4846 m_hBAFModule = NULL;
4847 m_pfnBAFunctionsProc = NULL;
4848 m_pvBAFunctionsProcContext = NULL;
4849
4850 C_ASSERT(0 == WIXSTDBA_CONTROL_INSTALL_BUTTON - WIXSTDBA_FIRST_ASSIGN_CONTROL_ID);
4851 pAssignControl = m_rgInitControls;
4852
4853 pAssignControl->wId = WIXSTDBA_CONTROL_INSTALL_BUTTON;
4854 pAssignControl->wzName = L"InstallButton";
4855 pAssignControl->ppControl = &m_pControlInstallButton;
4856 pAssignControl->dwAutomaticBehaviorType = dwAutomaticBehaviorType;
4857 m_pControlInstallButton = NULL;
4858 ++pAssignControl;
4859
4860 pAssignControl->wId = WIXSTDBA_CONTROL_EULA_RICHEDIT;
4861 pAssignControl->wzName = L"EulaRichedit";
4862 pAssignControl->ppControl = &m_pControlEulaRichedit;
4863 pAssignControl->dwAutomaticBehaviorType = dwAutomaticBehaviorType;
4864 m_pControlEulaRichedit = NULL;
4865 ++pAssignControl;
4866
4867 pAssignControl->wId = WIXSTDBA_CONTROL_EULA_LINK;
4868 pAssignControl->wzName = L"EulaHyperlink";
4869 pAssignControl->ppControl = &m_pControlEulaHyperlink;
4870 pAssignControl->dwAutomaticBehaviorType = dwAutomaticBehaviorType;
4871 m_pControlEulaHyperlink = NULL;
4872 ++pAssignControl;
4873
4874 pAssignControl->wId = WIXSTDBA_CONTROL_EULA_ACCEPT_CHECKBOX;
4875 pAssignControl->wzName = L"EulaAcceptCheckbox";
4876 pAssignControl->ppControl = &m_pControlEulaAcceptCheckbox;
4877 pAssignControl->dwAutomaticBehaviorType = dwAutomaticBehaviorType;
4878 m_pControlEulaAcceptCheckbox = NULL;
4879 ++pAssignControl;
4880
4881 pAssignControl->wId = WIXSTDBA_CONTROL_REPAIR_BUTTON;
4882 pAssignControl->wzName = L"RepairButton";
4883 pAssignControl->ppControl = &m_pControlRepairButton;
4884 pAssignControl->dwAutomaticBehaviorType = dwAutomaticBehaviorType;
4885 m_pControlRepairButton = NULL;
4886 ++pAssignControl;
4887
4888 pAssignControl->wId = WIXSTDBA_CONTROL_UNINSTALL_BUTTON;
4889 pAssignControl->wzName = L"UninstallButton";
4890 pAssignControl->ppControl = &m_pControlUninstallButton;
4891 pAssignControl->dwAutomaticBehaviorType = dwAutomaticBehaviorType;
4892 m_pControlUninstallButton = NULL;
4893 ++pAssignControl;
4894
4895 pAssignControl->wId = WIXSTDBA_CONTROL_CHECKING_FOR_UPDATES_LABEL;
4896 pAssignControl->wzName = L"CheckingForUpdatesLabel";
4897 pAssignControl->ppControl = &m_pControlCheckingForUpdatesLabel;
4898 pAssignControl->dwAutomaticBehaviorType = dwAutomaticBehaviorType;
4899 m_pControlCheckingForUpdatesLabel = NULL;
4900 ++pAssignControl;
4901
4902 pAssignControl->wId = WIXSTDBA_CONTROL_INSTALL_UPDATE_BUTTON;
4903 pAssignControl->wzName = L"InstallUpdateButton";
4904 pAssignControl->ppControl = &m_pControlInstallUpdateButton;
4905 pAssignControl->dwAutomaticBehaviorType = THEME_CONTROL_AUTOMATIC_BEHAVIOR_ALL;
4906 m_pControlInstallUpdateButton = NULL;
4907 ++pAssignControl;
4908
4909 pAssignControl->wId = WIXSTDBA_CONTROL_MODIFY_UPDATE_BUTTON;
4910 pAssignControl->wzName = L"ModifyUpdateButton";
4911 pAssignControl->ppControl = &m_pControlModifyUpdateButton;
4912 pAssignControl->dwAutomaticBehaviorType = THEME_CONTROL_AUTOMATIC_BEHAVIOR_ALL;
4913 m_pControlModifyUpdateButton = NULL;
4914 ++pAssignControl;
4915
4916 pAssignControl->wId = WIXSTDBA_CONTROL_CACHE_PROGRESS_PACKAGE_TEXT;
4917 pAssignControl->wzName = L"CacheProgressPackageText";
4918 pAssignControl->ppControl = &m_pControlCacheProgressPackageText;
4919 pAssignControl->dwAutomaticBehaviorType = dwAutomaticBehaviorType;
4920 m_pControlCacheProgressPackageText = NULL;
4921 ++pAssignControl;
4922
4923 pAssignControl->wId = WIXSTDBA_CONTROL_CACHE_PROGRESS_BAR;
4924 pAssignControl->wzName = L"CacheProgressbar";
4925 pAssignControl->ppControl = &m_pControlCacheProgressbar;
4926 pAssignControl->dwAutomaticBehaviorType = dwAutomaticBehaviorType;
4927 m_pControlCacheProgressbar = NULL;
4928 ++pAssignControl;
4929
4930 pAssignControl->wId = WIXSTDBA_CONTROL_CACHE_PROGRESS_TEXT;
4931 pAssignControl->wzName = L"CacheProgressText";
4932 pAssignControl->ppControl = &m_pControlCacheProgressText;
4933 pAssignControl->dwAutomaticBehaviorType = dwAutomaticBehaviorType;
4934 m_pControlCacheProgressText = NULL;
4935 ++pAssignControl;
4936
4937 pAssignControl->wId = WIXSTDBA_CONTROL_EXECUTE_PROGRESS_PACKAGE_TEXT;
4938 pAssignControl->wzName = L"ExecuteProgressPackageText";
4939 pAssignControl->ppControl = &m_pControlExecuteProgressPackageText;
4940 pAssignControl->dwAutomaticBehaviorType = dwAutomaticBehaviorType;
4941 m_pControlExecuteProgressPackageText = NULL;
4942 ++pAssignControl;
4943
4944 pAssignControl->wId = WIXSTDBA_CONTROL_EXECUTE_PROGRESS_BAR;
4945 pAssignControl->wzName = L"ExecuteProgressbar";
4946 pAssignControl->ppControl = &m_pControlExecuteProgressbar;
4947 pAssignControl->dwAutomaticBehaviorType = dwAutomaticBehaviorType;
4948 m_pControlExecuteProgressbar = NULL;
4949 ++pAssignControl;
4950
4951 pAssignControl->wId = WIXSTDBA_CONTROL_EXECUTE_PROGRESS_TEXT;
4952 pAssignControl->wzName = L"ExecuteProgressText";
4953 pAssignControl->ppControl = &m_pControlExecuteProgressText;
4954 pAssignControl->dwAutomaticBehaviorType = dwAutomaticBehaviorType;
4955 m_pControlExecuteProgressText = NULL;
4956 ++pAssignControl;
4957
4958 pAssignControl->wId = WIXSTDBA_CONTROL_EXECUTE_PROGRESS_ACTIONDATA_TEXT;
4959 pAssignControl->wzName = L"ExecuteProgressActionDataText";
4960 pAssignControl->ppControl = &m_pControlExecuteProgressActionDataText;
4961 pAssignControl->dwAutomaticBehaviorType = dwAutomaticBehaviorType;
4962 m_pControlExecuteProgressActionDataText = NULL;
4963 ++pAssignControl;
4964
4965 pAssignControl->wId = WIXSTDBA_CONTROL_OVERALL_PROGRESS_PACKAGE_TEXT;
4966 pAssignControl->wzName = L"OverallProgressPackageText";
4967 pAssignControl->ppControl = &m_pControlOverallProgressPackageText;
4968 pAssignControl->dwAutomaticBehaviorType = dwAutomaticBehaviorType;
4969 m_pControlOverallProgressPackageText = NULL;
4970 ++pAssignControl;
4971
4972 pAssignControl->wId = WIXSTDBA_CONTROL_OVERALL_PROGRESS_BAR;
4973 pAssignControl->wzName = L"OverallProgressbar";
4974 pAssignControl->ppControl = &m_pControlOverallProgressbar;
4975 pAssignControl->dwAutomaticBehaviorType = dwAutomaticBehaviorType;
4976 m_pControlOverallProgressbar = NULL;
4977 ++pAssignControl;
4978
4979 pAssignControl->wId = WIXSTDBA_CONTROL_OVERALL_CALCULATED_PROGRESS_BAR;
4980 pAssignControl->wzName = L"OverallCalculatedProgressbar";
4981 pAssignControl->ppControl = &m_pControlOverallCalculatedProgressbar;
4982 pAssignControl->dwAutomaticBehaviorType = dwAutomaticBehaviorType;
4983 m_pControlOverallCalculatedProgressbar = NULL;
4984 ++pAssignControl;
4985
4986 pAssignControl->wId = WIXSTDBA_CONTROL_OVERALL_PROGRESS_TEXT;
4987 pAssignControl->wzName = L"OverallProgressText";
4988 pAssignControl->ppControl = &m_pControlOverallProgressText;
4989 pAssignControl->dwAutomaticBehaviorType = dwAutomaticBehaviorType;
4990 m_pControlOverallProgressText = NULL;
4991 ++pAssignControl;
4992
4993 pAssignControl->wId = WIXSTDBA_CONTROL_PROGRESS_CANCEL_BUTTON;
4994 pAssignControl->wzName = L"ProgressCancelButton";
4995 pAssignControl->ppControl = &m_pControlProgressCancelButton;
4996 pAssignControl->dwAutomaticBehaviorType = dwAutomaticBehaviorType;
4997 m_pControlProgressCancelButton = NULL;
4998 ++pAssignControl;
4999
5000 pAssignControl->wId = WIXSTDBA_CONTROL_LAUNCH_BUTTON;
5001 pAssignControl->wzName = L"LaunchButton";
5002 pAssignControl->ppControl = &m_pControlLaunchButton;
5003 pAssignControl->dwAutomaticBehaviorType = dwAutomaticBehaviorType;
5004 m_pControlLaunchButton = NULL;
5005 ++pAssignControl;
5006
5007 pAssignControl->wId = WIXSTDBA_CONTROL_SUCCESS_RESTART_BUTTON;
5008 pAssignControl->wzName = L"SuccessRestartButton";
5009 pAssignControl->ppControl = &m_pControlSuccessRestartButton;
5010 pAssignControl->dwAutomaticBehaviorType = dwAutomaticBehaviorType;
5011 m_pControlSuccessRestartButton = NULL;
5012 ++pAssignControl;
5013
5014 pAssignControl->wId = WIXSTDBA_CONTROL_FAILURE_LOGFILE_LINK;
5015 pAssignControl->wzName = L"FailureLogFileLink";
5016 pAssignControl->ppControl = &m_pControlFailureLogFileLink;
5017 pAssignControl->dwAutomaticBehaviorType = dwAutomaticBehaviorType;
5018 m_pControlFailureLogFileLink = NULL;
5019 ++pAssignControl;
5020
5021 pAssignControl->wId = WIXSTDBA_CONTROL_FAILURE_MESSAGE_TEXT;
5022 pAssignControl->wzName = L"FailureMessageText";
5023 pAssignControl->ppControl = &m_pControlFailureMessageText;
5024 pAssignControl->dwAutomaticBehaviorType = dwAutomaticBehaviorType;
5025 m_pControlFailureMessageText = NULL;
5026 ++pAssignControl;
5027
5028 pAssignControl->wId = WIXSTDBA_CONTROL_FAILURE_RESTART_BUTTON;
5029 pAssignControl->wzName = L"FailureRestartButton";
5030 pAssignControl->ppControl = &m_pControlFailureRestartButton;
5031 pAssignControl->dwAutomaticBehaviorType = dwAutomaticBehaviorType;
5032 m_pControlFailureRestartButton = NULL;
5033
5034 C_ASSERT(LAST_WIXSTDBA_CONTROL == WIXSTDBA_CONTROL_FAILURE_RESTART_BUTTON + 1);
5035 }
5036
5037
5038 //
5039 // Destructor - release member variables.
5040 //
5041 ~CWixStandardBootstrapperApplication()
5042 {
5043 AssertSz(!::IsWindow(m_hWnd), "Window should have been destroyed before destructor.");
5044 AssertSz(!m_pTaskbarList, "Taskbar should have been released before destructor.");
5045 AssertSz(!m_pTheme, "Theme should have been released before destructor.");
5046
5047 ::DeleteCriticalSection(&m_csShowingInternalUiThisPackage);
5048 ReleaseStr(m_sczFailedMessage);
5049 ReleaseStr(m_sczConfirmCloseMessage);
5050 BalConditionsUninitialize(&m_Conditions);
5051 BalInfoUninitialize(&m_Bundle);
5052 LocFree(m_pWixLoc);
5053
5054 ReleaseStr(m_sczLanguage);
5055 ReleaseStr(m_sczLicenseFile);
5056 ReleaseStr(m_sczLicenseUrl);
5057 ReleaseStr(m_sczBundleVersion);
5058 ReleaseStr(m_sczAfterForcedRestartPackage);
5059
5060 ReleaseNullObject(m_pEngine);
5061 }
5062
5063private:
5064 HMODULE m_hModule;
5065 BOOTSTRAPPER_CREATE_ARGS m_createArgs;
5066 BOOTSTRAPPER_COMMAND m_command;
5067 IBootstrapperEngine* m_pEngine;
5068 BOOTSTRAPPER_ACTION m_plannedAction;
5069
5070 LPWSTR m_sczAfterForcedRestartPackage;
5071 LPWSTR m_sczBundleVersion;
5072
5073 WIX_LOCALIZATION* m_pWixLoc;
5074 BAL_INFO_BUNDLE m_Bundle;
5075 BAL_CONDITIONS m_Conditions;
5076 LPWSTR m_sczFailedMessage;
5077 LPWSTR m_sczConfirmCloseMessage;
5078
5079 LPWSTR m_sczLanguage;
5080 THEME* m_pTheme;
5081 THEME_ASSIGN_CONTROL_ID m_rgInitControls[LAST_WIXSTDBA_CONTROL - WIXSTDBA_FIRST_ASSIGN_CONTROL_ID];
5082 DWORD m_rgdwPageIds[countof(vrgwzPageNames)];
5083 HANDLE m_hUiThread;
5084 BOOL m_fRegistered;
5085 HWND m_hWnd;
5086
5087 // Welcome page
5088 const THEME_CONTROL* m_pControlInstallButton;
5089 const THEME_CONTROL* m_pControlEulaRichedit;
5090 const THEME_CONTROL* m_pControlEulaHyperlink;
5091 const THEME_CONTROL* m_pControlEulaAcceptCheckbox;
5092
5093 // Modify page
5094 const THEME_CONTROL* m_pControlRepairButton;
5095 const THEME_CONTROL* m_pControlUninstallButton;
5096
5097 // Update/loading pages
5098 const THEME_CONTROL* m_pControlCheckingForUpdatesLabel;
5099 const THEME_CONTROL* m_pControlInstallUpdateButton;
5100 const THEME_CONTROL* m_pControlModifyUpdateButton;
5101
5102 // Progress page
5103 const THEME_CONTROL* m_pControlCacheProgressPackageText;
5104 const THEME_CONTROL* m_pControlCacheProgressbar;
5105 const THEME_CONTROL* m_pControlCacheProgressText;
5106
5107 const THEME_CONTROL* m_pControlExecuteProgressPackageText;
5108 const THEME_CONTROL* m_pControlExecuteProgressbar;
5109 const THEME_CONTROL* m_pControlExecuteProgressText;
5110 const THEME_CONTROL* m_pControlExecuteProgressActionDataText;
5111
5112 const THEME_CONTROL* m_pControlOverallProgressPackageText;
5113 const THEME_CONTROL* m_pControlOverallProgressbar;
5114 const THEME_CONTROL* m_pControlOverallCalculatedProgressbar;
5115 const THEME_CONTROL* m_pControlOverallProgressText;
5116
5117 const THEME_CONTROL* m_pControlProgressCancelButton;
5118
5119 // Success page
5120 const THEME_CONTROL* m_pControlLaunchButton;
5121 const THEME_CONTROL* m_pControlSuccessRestartButton;
5122
5123 // Failure page
5124 const THEME_CONTROL* m_pControlFailureLogFileLink;
5125 const THEME_CONTROL* m_pControlFailureMessageText;
5126 const THEME_CONTROL* m_pControlFailureRestartButton;
5127
5128 WIXSTDBA_STATE m_state;
5129 HRESULT m_hrFinal;
5130
5131 BOOL m_fStartedExecution;
5132 DWORD m_dwCalculatedCacheProgress;
5133 DWORD m_dwCalculatedExecuteProgress;
5134
5135 BOOTSTRAPPER_APPLY_RESTART m_restartResult;
5136 BOOL m_fRestartRequired;
5137 BOOL m_fShouldRestart;
5138 BOOL m_fAllowRestart;
5139 BOOL m_fRestartRequiresElevation;
5140 BOOL m_fElevatingForRestart;
5141
5142 LPWSTR m_sczLicenseFile;
5143 LPWSTR m_sczLicenseUrl;
5144 BOOL m_fSuppressDowngradeFailure;
5145 BOOL m_fDowngrading;
5146 BOOL m_fSuppressRepair;
5147 BOOL m_fSupportCacheOnly;
5148 BOOL m_fRequestedCacheOnly;
5149
5150 PREQBA_DATA* m_pPrereqData;
5151 BOOL m_fPrereq;
5152 BOOL m_fPreplanPrereqs;
5153 BOOL m_fPerformHelp;
5154 BOOL m_fPrereqPackagePlanned;
5155 BOOL m_fPrereqInstalled;
5156 BOOL m_fPrereqSkipped;
5157
5158 ITaskbarList3* m_pTaskbarList;
5159 UINT m_uTaskbarButtonCreatedMessage;
5160 BOOL m_fTaskbarButtonOK;
5161 CRITICAL_SECTION m_csShowingInternalUiThisPackage;
5162 BOOL m_fShowingInternalUiThisPackage;
5163 BOOL m_fTriedToLaunchElevated;
5164
5165 BOOL m_fShowStandardFilesInUse;
5166 BOOL m_fShowRMFilesInUse;
5167 BOOL m_fShowNetfxFilesInUse;
5168 int m_nLastMsiFilesInUseResult;
5169 int m_nLastNetfxFilesInUseResult;
5170 LOC_STRING* m_pFilesInUseTitleLoc;
5171 LOC_STRING* m_pFilesInUseLabelLoc;
5172 LOC_STRING* m_pFilesInUseCloseRadioButtonLoc;
5173 LOC_STRING* m_pFilesInUseNetfxCloseRadioButtonLoc;
5174 LOC_STRING* m_pFilesInUseDontCloseRadioButtonLoc;
5175 LOC_STRING* m_pFilesInUseRetryButtonLoc;
5176 LOC_STRING* m_pFilesInUseIgnoreButtonLoc;
5177 LOC_STRING* m_pFilesInUseExitButtonLoc;
5178
5179 HMODULE m_hBAFModule;
5180 PFN_BA_FUNCTIONS_PROC m_pfnBAFunctionsProc;
5181 LPVOID m_pvBAFunctionsProcContext;
5182};
5183
5184
5185//
5186// CreateBootstrapperApplication - creates a new IBootstrapperApplication object.
5187//
5188HRESULT CreateBootstrapperApplication(
5189 __in HMODULE hModule,
5190 __in_opt PREQBA_DATA* pPrereqData,
5191 __in IBootstrapperEngine* pEngine,
5192 __in const BOOTSTRAPPER_CREATE_ARGS* pArgs,
5193 __inout BOOTSTRAPPER_CREATE_RESULTS* pResults,
5194 __out IBootstrapperApplication** ppApplication
5195 )
5196{
5197 HRESULT hr = S_OK;
5198 CWixStandardBootstrapperApplication* pApplication = NULL;
5199
5200 if (BOOTSTRAPPER_DISPLAY_UNKNOWN == pArgs->pCommand->display)
5201 {
5202 BalExitOnFailure(hr = E_INVALIDARG, "Engine requested Unknown display type.");
5203 }
5204
5205 pApplication = new CWixStandardBootstrapperApplication(hModule, pPrereqData, pEngine);
5206 BalExitOnNull(pApplication, hr, E_OUTOFMEMORY, "Failed to create new standard bootstrapper application object.");
5207
5208 hr = pApplication->Initialize(pArgs);
5209 ExitOnFailure(hr, "CWixStandardBootstrapperApplication initialization failed.");
5210
5211 pResults->pfnBootstrapperApplicationProc = BalBaseBootstrapperApplicationProc;
5212 pResults->pvBootstrapperApplicationProcContext = pApplication;
5213 *ppApplication = pApplication;
5214 pApplication = NULL;
5215
5216LExit:
5217 ReleaseObject(pApplication);
5218 return hr;
5219}
5220
5221
5222void DestroyBootstrapperApplication(
5223 __in IBootstrapperApplication* pApplication,
5224 __in const BOOTSTRAPPER_DESTROY_ARGS* pArgs,
5225 __inout BOOTSTRAPPER_DESTROY_RESULTS* pResults
5226 )
5227{
5228 CWixStandardBootstrapperApplication* pBA = (CWixStandardBootstrapperApplication*)pApplication;
5229 pBA->Uninitialize(pArgs, pResults);
5230}
5231
5232
5233static HRESULT DAPI EvaluateVariableConditionCallback(
5234 __in_z LPCWSTR wzCondition,
5235 __out BOOL* pf,
5236 __in_opt LPVOID /*pvContext*/
5237 )
5238{
5239 return BalEvaluateCondition(wzCondition, pf);
5240}
5241
5242
5243static HRESULT DAPI FormatVariableStringCallback(
5244 __in_z LPCWSTR wzFormat,
5245 __inout LPWSTR* psczOut,
5246 __in_opt LPVOID /*pvContext*/
5247 )
5248{
5249 return BalFormatString(wzFormat, psczOut);
5250}
5251
5252
5253static HRESULT DAPI GetVariableNumericCallback(
5254 __in_z LPCWSTR wzVariable,
5255 __out LONGLONG* pllValue,
5256 __in_opt LPVOID /*pvContext*/
5257 )
5258{
5259 return BalGetNumericVariable(wzVariable, pllValue);
5260}
5261
5262
5263static HRESULT DAPI SetVariableNumericCallback(
5264 __in_z LPCWSTR wzVariable,
5265 __in LONGLONG llValue,
5266 __in_opt LPVOID /*pvContext*/
5267 )
5268{
5269 return BalSetNumericVariable(wzVariable, llValue);
5270}
5271
5272
5273static HRESULT DAPI GetVariableStringCallback(
5274 __in_z LPCWSTR wzVariable,
5275 __inout LPWSTR* psczValue,
5276 __in_opt LPVOID /*pvContext*/
5277 )
5278{
5279 return BalGetStringVariable(wzVariable, psczValue);
5280}
5281
5282
5283static HRESULT DAPI SetVariableStringCallback(
5284 __in_z LPCWSTR wzVariable,
5285 __in_z_opt LPCWSTR wzValue,
5286 __in BOOL fFormatted,
5287 __in_opt LPVOID /*pvContext*/
5288 )
5289{
5290 return BalSetStringVariable(wzVariable, wzValue, fFormatted);
5291}
5292
5293static LPCSTR LoggingBoolToString(
5294 __in BOOL f
5295 )
5296{
5297 if (f)
5298 {
5299 return "Yes";
5300 }
5301
5302 return "No";
5303}
5304
5305static LPCSTR LoggingRequestStateToString(
5306 __in BOOTSTRAPPER_REQUEST_STATE requestState
5307 )
5308{
5309 switch (requestState)
5310 {
5311 case BOOTSTRAPPER_REQUEST_STATE_NONE:
5312 return "None";
5313 case BOOTSTRAPPER_REQUEST_STATE_FORCE_ABSENT:
5314 return "ForceAbsent";
5315 case BOOTSTRAPPER_REQUEST_STATE_ABSENT:
5316 return "Absent";
5317 case BOOTSTRAPPER_REQUEST_STATE_CACHE:
5318 return "Cache";
5319 case BOOTSTRAPPER_REQUEST_STATE_PRESENT:
5320 return "Present";
5321 case BOOTSTRAPPER_REQUEST_STATE_REPAIR:
5322 return "Repair";
5323 default:
5324 return "Invalid";
5325 }
5326}
5327
5328static LPCSTR LoggingPlanRelationTypeToString(
5329 __in BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE type
5330 )
5331{
5332 switch (type)
5333 {
5334 case BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_NONE:
5335 return "None";
5336 case BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_DOWNGRADE:
5337 return "Downgrade";
5338 case BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_UPGRADE:
5339 return "Upgrade";
5340 case BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_ADDON:
5341 return "Addon";
5342 case BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_PATCH:
5343 return "Patch";
5344 case BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_DEPENDENT_ADDON:
5345 return "DependentAddon";
5346 case BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_DEPENDENT_PATCH:
5347 return "DependentPatch";
5348 default:
5349 return "Invalid";
5350 }
5351}
5352
5353static LPCSTR LoggingMsiFeatureStateToString(
5354 __in BOOTSTRAPPER_FEATURE_STATE featureState
5355 )
5356{
5357 switch (featureState)
5358 {
5359 case BOOTSTRAPPER_FEATURE_STATE_UNKNOWN:
5360 return "Unknown";
5361 case BOOTSTRAPPER_FEATURE_STATE_ABSENT:
5362 return "Absent";
5363 case BOOTSTRAPPER_FEATURE_STATE_ADVERTISED:
5364 return "Advertised";
5365 case BOOTSTRAPPER_FEATURE_STATE_LOCAL:
5366 return "Local";
5367 case BOOTSTRAPPER_FEATURE_STATE_SOURCE:
5368 return "Source";
5369 default:
5370 return "Invalid";
5371 }
5372}