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