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