summaryrefslogtreecommitdiff
path: root/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2022-05-13 13:50:50 -0500
committerSean Hall <r.sean.hall@gmail.com>2022-05-14 11:12:31 -0500
commit6a6974a15deb6edf593736cdb8043bfb93064782 (patch)
tree0ae2afffcd02967ba3fe0f0a5d3e9273811f1e6f /src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp
parent7d56566b7c51c49ded526466dfae6af9e1709040 (diff)
downloadwix-6a6974a15deb6edf593736cdb8043bfb93064782.tar.gz
wix-6a6974a15deb6edf593736cdb8043bfb93064782.tar.bz2
wix-6a6974a15deb6edf593736cdb8043bfb93064782.zip
Move infinite loop detection into the hosts.
Tell the BA during Destroy whether it will be reloaded, and let the BA decide then whether it's module should be unloaded. Show error when infinite prereq loop detected. Only clip the exit code if they're Win32 errors. Set related bundle type to none to avoid downgrades during preqba.
Diffstat (limited to 'src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp')
-rw-r--r--src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp320
1 files changed, 102 insertions, 218 deletions
diff --git a/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp b/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp
index dd00a563..3774f49c 100644
--- a/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp
+++ b/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp
@@ -123,14 +123,6 @@ enum WIXSTDBA_CONTROL
123 LAST_WIXSTDBA_CONTROL, 123 LAST_WIXSTDBA_CONTROL,
124}; 124};
125 125
126typedef struct _WIXSTDBA_PACKAGE_INFO
127{
128 LPWSTR sczPackageId;
129 BOOL fWasAlreadyInstalled;
130 BOOL fPlannedToBeInstalled;
131 BOOL fSuccessfullyInstalled;
132} WIXSTDBA_PACKAGE_INFO;
133
134 126
135static HRESULT DAPI EvaluateVariableConditionCallback( 127static HRESULT DAPI EvaluateVariableConditionCallback(
136 __in_z LPCWSTR wzCondition, 128 __in_z LPCWSTR wzCondition,
@@ -229,10 +221,7 @@ public: // IBootstrapperApplication
229 { 221 {
230 BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "The prerequisites were successfully installed. The bootstrapper application will be reloaded."); 222 BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "The prerequisites were successfully installed. The bootstrapper application will be reloaded.");
231 *pAction = BOOTSTRAPPER_SHUTDOWN_ACTION_RELOAD_BOOTSTRAPPER; 223 *pAction = BOOTSTRAPPER_SHUTDOWN_ACTION_RELOAD_BOOTSTRAPPER;
232 } 224 m_pPrereqData->fCompleted = TRUE;
233 else if (m_fPrereqAlreadyInstalled)
234 {
235 BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "The prerequisites were already installed. The bootstrapper application will not be reloaded to prevent an infinite loop.");
236 } 225 }
237 else if (m_fPrereq) 226 else if (m_fPrereq)
238 { 227 {
@@ -311,38 +300,14 @@ public: // IBootstrapperApplication
311 300
312 if (!fMissingFromCache) 301 if (!fMissingFromCache)
313 { 302 {
314 if (SUCCEEDED(BalInfoAddRelatedBundleAsPackage(&m_Bundle.packages, wzBundleId, relationType, fPerMachine, &pPackage))) 303 BalInfoAddRelatedBundleAsPackage(&m_Bundle.packages, wzBundleId, relationType, fPerMachine, &pPackage);
315 { 304 // Best effort
316 InitializePackageInfoForPackage(pPackage);
317 }
318 } 305 }
319 306
320 return CBalBaseBootstrapperApplication::OnDetectRelatedBundle(wzBundleId, relationType, wzBundleTag, fPerMachine, wzVersion, fMissingFromCache, pfCancel); 307 return CBalBaseBootstrapperApplication::OnDetectRelatedBundle(wzBundleId, relationType, wzBundleTag, fPerMachine, wzVersion, fMissingFromCache, pfCancel);
321 } 308 }
322 309
323 310
324 virtual STDMETHODIMP OnDetectPackageComplete(
325 __in LPCWSTR wzPackageId,
326 __in HRESULT /*hrStatus*/,
327 __in BOOTSTRAPPER_PACKAGE_STATE state,
328 __in BOOL /*fCached*/
329 )
330 {
331 WIXSTDBA_PACKAGE_INFO* pPackageInfo = NULL;
332 BAL_INFO_PACKAGE* pPackage = NULL;
333
334 if (BOOTSTRAPPER_PACKAGE_STATE_PRESENT == state &&
335 SUCCEEDED(GetPackageInfo(wzPackageId, &pPackageInfo, &pPackage)) &&
336 pPackageInfo)
337 {
338 // If the package is already installed, remember that.
339 pPackageInfo->fWasAlreadyInstalled = TRUE;
340 }
341
342 return S_OK;
343 }
344
345
346 virtual STDMETHODIMP OnDetectComplete( 311 virtual STDMETHODIMP OnDetectComplete(
347 __in HRESULT hrStatus, 312 __in HRESULT hrStatus,
348 __in BOOL /*fEligibleForCleanup*/ 313 __in BOOL /*fEligibleForCleanup*/
@@ -366,29 +331,10 @@ public: // IBootstrapperApplication
366 if (fEvaluateConditions) 331 if (fEvaluateConditions)
367 { 332 {
368 hrStatus = EvaluateConditions(); 333 hrStatus = EvaluateConditions();
369 }
370 334
371 if (FAILED(hrStatus)) 335 if (FAILED(hrStatus))
372 {
373 fSkipToPlan = FALSE;
374 }
375 else
376 {
377 if (m_fPrereq)
378 { 336 {
379 m_fPrereqAlreadyInstalled = TRUE; 337 fSkipToPlan = FALSE;
380
381 // At this point we have to assume that all prerequisite packages need to be installed, so set to false if any of them aren't installed.
382 for (DWORD i = 0; i < m_Bundle.packages.cPackages; ++i)
383 {
384 BAL_INFO_PACKAGE* pPackage = &m_Bundle.packages.rgPackages[i];
385 WIXSTDBA_PACKAGE_INFO* pPackageInfo = reinterpret_cast<WIXSTDBA_PACKAGE_INFO*>(pPackage->pvCustomData);
386 if (pPackage->fPrereqPackage && pPackageInfo && !pPackageInfo->fWasAlreadyInstalled)
387 {
388 m_fPrereqAlreadyInstalled = FALSE;
389 break;
390 }
391 }
392 } 338 }
393 } 339 }
394 340
@@ -403,20 +349,20 @@ public: // IBootstrapperApplication
403 } 349 }
404 350
405 351
406 virtual STDMETHODIMP OnPlanRelatedBundle( 352 virtual STDMETHODIMP OnPlanRelatedBundleType(
407 __in_z LPCWSTR wzBundleId, 353 __in_z LPCWSTR wzBundleId,
408 __in BOOTSTRAPPER_REQUEST_STATE recommendedState, 354 __in BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE recommendedType,
409 __inout_z BOOTSTRAPPER_REQUEST_STATE* pRequestedState, 355 __inout BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE* pRequestedType,
410 __inout BOOL* pfCancel 356 __inout BOOL* pfCancel
411 ) 357 )
412 { 358 {
413 // If we're only installing prerequisites, do not touch related bundles. 359 // If we're only installing prerequisites, do not touch related bundles.
414 if (m_fPrereq) 360 if (m_fPrereq)
415 { 361 {
416 *pRequestedState = BOOTSTRAPPER_REQUEST_STATE_NONE; 362 *pRequestedType = BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_NONE;
417 } 363 }
418 364
419 return CBalBaseBootstrapperApplication::OnPlanRelatedBundle(wzBundleId, recommendedState, pRequestedState, pfCancel); 365 return CBalBaseBootstrapperApplication::OnPlanRelatedBundleType(wzBundleId, recommendedType, pRequestedType, pfCancel);
420 } 366 }
421 367
422 368
@@ -434,7 +380,6 @@ public: // IBootstrapperApplication
434 ) 380 )
435 { 381 {
436 HRESULT hr = S_OK; 382 HRESULT hr = S_OK;
437 WIXSTDBA_PACKAGE_INFO* pPackageInfo = NULL;
438 BAL_INFO_PACKAGE* pPackage = NULL; 383 BAL_INFO_PACKAGE* pPackage = NULL;
439 384
440 // If we're planning to install prerequisites, install them. The prerequisites need to be installed 385 // If we're planning to install prerequisites, install them. The prerequisites need to be installed
@@ -443,10 +388,11 @@ public: // IBootstrapperApplication
443 { 388 {
444 // Only install prerequisite packages, and check the InstallCondition on them. 389 // Only install prerequisite packages, and check the InstallCondition on them.
445 BOOL fInstall = FALSE; 390 BOOL fInstall = FALSE;
446 hr = GetPackageInfo(wzPackageId, &pPackageInfo, &pPackage); 391
447 if (SUCCEEDED(hr) && pPackage->fPrereqPackage && pPackageInfo) 392 hr = BalInfoFindPackageById(&m_Bundle.packages, wzPackageId, &pPackage);
393 if (SUCCEEDED(hr) && pPackage->fPrereqPackage)
448 { 394 {
449 pPackageInfo->fPlannedToBeInstalled = fInstall = BOOTSTRAPPER_PACKAGE_CONDITION_FALSE != installCondition; 395 fInstall = BOOTSTRAPPER_PACKAGE_CONDITION_FALSE != installCondition;
450 } 396 }
451 397
452 if (fInstall) 398 if (fInstall)
@@ -503,7 +449,6 @@ public: // IBootstrapperApplication
503 ) 449 )
504 { 450 {
505 HRESULT hr = S_OK; 451 HRESULT hr = S_OK;
506 WIXSTDBA_PACKAGE_INFO* pPackageInfo = NULL;
507 BAL_INFO_PACKAGE* pPackage = NULL; 452 BAL_INFO_PACKAGE* pPackage = NULL;
508 BOOL fShowInternalUI = FALSE; 453 BOOL fShowInternalUI = FALSE;
509 INSTALLUILEVEL uiLevel = INSTALLUILEVEL_NOCHANGE; 454 INSTALLUILEVEL uiLevel = INSTALLUILEVEL_NOCHANGE;
@@ -521,7 +466,7 @@ public: // IBootstrapperApplication
521 466
522 if (INSTALLUILEVEL_NOCHANGE != uiLevel) 467 if (INSTALLUILEVEL_NOCHANGE != uiLevel)
523 { 468 {
524 hr = GetPackageInfo(wzPackageId, &pPackageInfo, &pPackage); 469 hr = BalInfoFindPackageById(&m_Bundle.packages, wzPackageId, &pPackage);
525 if (SUCCEEDED(hr) && pPackage->sczDisplayInternalUICondition) 470 if (SUCCEEDED(hr) && pPackage->sczDisplayInternalUICondition)
526 { 471 {
527 hr = BalEvaluateCondition(pPackage->sczDisplayInternalUICondition, &fShowInternalUI); 472 hr = BalEvaluateCondition(pPackage->sczDisplayInternalUICondition, &fShowInternalUI);
@@ -545,23 +490,6 @@ public: // IBootstrapperApplication
545 { 490 {
546 HRESULT hr = S_OK; 491 HRESULT hr = S_OK;
547 492
548 if (m_fPrereq)
549 {
550 m_fPrereqAlreadyInstalled = TRUE;
551
552 // Now that we've planned the packages, we can focus on the prerequisite packages that are supposed to be installed.
553 for (DWORD i = 0; i < m_Bundle.packages.cPackages; ++i)
554 {
555 BAL_INFO_PACKAGE* pPackage = &m_Bundle.packages.rgPackages[i];
556 WIXSTDBA_PACKAGE_INFO* pPackageInfo = reinterpret_cast<WIXSTDBA_PACKAGE_INFO*>(pPackage->pvCustomData);
557 if (pPackage->fPrereqPackage && pPackageInfo && !pPackageInfo->fWasAlreadyInstalled && pPackageInfo->fPlannedToBeInstalled)
558 {
559 m_fPrereqAlreadyInstalled = FALSE;
560 break;
561 }
562 }
563 }
564
565 SetState(WIXSTDBA_STATE_PLANNED, hrStatus); 493 SetState(WIXSTDBA_STATE_PLANNED, hrStatus);
566 494
567 if (SUCCEEDED(hrStatus)) 495 if (SUCCEEDED(hrStatus))
@@ -1033,13 +961,10 @@ public: // IBootstrapperApplication
1033 961
1034 hr = __super::OnExecutePackageComplete(wzPackageId, hrStatus, restart, recommendation, pAction); 962 hr = __super::OnExecutePackageComplete(wzPackageId, hrStatus, restart, recommendation, pAction);
1035 963
1036 WIXSTDBA_PACKAGE_INFO* pPackageInfo = NULL; 964 BAL_INFO_PACKAGE* pPackage = NULL;
1037 BAL_INFO_PACKAGE* pPackage; 965 HRESULT hrPrereq = BalInfoFindPackageById(&m_Bundle.packages, wzPackageId, &pPackage);
1038 HRESULT hrPrereq = GetPackageInfo(wzPackageId, &pPackageInfo, &pPackage); 966 if (SUCCEEDED(hrPrereq))
1039 if (SUCCEEDED(hrPrereq) && pPackageInfo)
1040 { 967 {
1041 pPackageInfo->fSuccessfullyInstalled = SUCCEEDED(hrStatus);
1042
1043 // If the prerequisite required a restart (any restart) then do an immediate 968 // If the prerequisite required a restart (any restart) then do an immediate
1044 // restart to ensure that the bundle will get launched again post reboot. 969 // restart to ensure that the bundle will get launched again post reboot.
1045 if (m_fPrereq && pPackage->fPrereqPackage && BOOTSTRAPPER_APPLY_RESTART_NONE != restart) 970 if (m_fPrereq && pPackage->fPrereqPackage && BOOTSTRAPPER_APPLY_RESTART_NONE != restart)
@@ -1157,28 +1082,7 @@ public: // IBootstrapperApplication
1157 1082
1158 if (m_fPrereq) 1083 if (m_fPrereq)
1159 { 1084 {
1160 m_fPrereqInstalled = TRUE; 1085 m_fPrereqInstalled = SUCCEEDED(hrStatus);
1161 BOOL fInstalledAPackage = FALSE;
1162
1163 for (DWORD i = 0; i < m_Bundle.packages.cPackages; ++i)
1164 {
1165 BAL_INFO_PACKAGE* pPackage = &m_Bundle.packages.rgPackages[i];
1166 WIXSTDBA_PACKAGE_INFO* pPackageInfo = reinterpret_cast<WIXSTDBA_PACKAGE_INFO*>(pPackage->pvCustomData);
1167 if (pPackage->fPrereqPackage && pPackageInfo && pPackageInfo->fPlannedToBeInstalled && !pPackageInfo->fWasAlreadyInstalled)
1168 {
1169 if (pPackageInfo->fSuccessfullyInstalled)
1170 {
1171 fInstalledAPackage = TRUE;
1172 }
1173 else
1174 {
1175 m_fPrereqInstalled = FALSE;
1176 break;
1177 }
1178 }
1179 }
1180
1181 m_fPrereqInstalled = m_fPrereqInstalled && fInstalledAPackage;
1182 } 1086 }
1183 1087
1184 // If we are showing UI, wait a beat before moving to the final screen. 1088 // If we are showing UI, wait a beat before moving to the final screen.
@@ -1223,10 +1127,10 @@ public: // IBootstrapperApplication
1223 { 1127 {
1224 BAL_INFO_PACKAGE* pPackage = NULL; 1128 BAL_INFO_PACKAGE* pPackage = NULL;
1225 1129
1226 if (SUCCEEDED(hrStatus) && wzNewPackageId && 1130 if (SUCCEEDED(hrStatus) && wzNewPackageId)
1227 SUCCEEDED(BalInfoAddUpdateBundleAsPackage(&m_Bundle.packages, wzNewPackageId, wzPreviousPackageId, &pPackage)))
1228 { 1131 {
1229 InitializePackageInfoForPackage(pPackage); 1132 BalInfoAddUpdateBundleAsPackage(&m_Bundle.packages, wzNewPackageId, wzPreviousPackageId, &pPackage);
1133 // Best effort
1230 } 1134 }
1231 1135
1232 return S_OK; 1136 return S_OK;
@@ -2201,6 +2105,36 @@ public: //CBalBaseBootstrapperApplication
2201 return hr; 2105 return hr;
2202 } 2106 }
2203 2107
2108 void Uninitialize(
2109 __in const BOOTSTRAPPER_DESTROY_ARGS* pArgs,
2110 __in BOOTSTRAPPER_DESTROY_RESULTS* /*pResults*/
2111 )
2112 {
2113 if (m_hBAFModule)
2114 {
2115 BA_FUNCTIONS_DESTROY_ARGS args = { };
2116 BA_FUNCTIONS_DESTROY_RESULTS results = { };
2117
2118 args.cbSize = sizeof(BA_FUNCTIONS_DESTROY_ARGS);
2119 args.fReload = pArgs->fReload;
2120
2121 results.cbSize = sizeof(BA_FUNCTIONS_DESTROY_RESULTS);
2122
2123 PFN_BA_FUNCTIONS_DESTROY pfnBAFunctionsDestroy = reinterpret_cast<PFN_BA_FUNCTIONS_DESTROY>(::GetProcAddress(m_hBAFModule, "BAFunctionsDestroy"));
2124 if (pfnBAFunctionsDestroy)
2125 {
2126 pfnBAFunctionsDestroy(&args, &results);
2127 }
2128
2129 if (!results.fDisableUnloading)
2130 {
2131 ::FreeLibrary(m_hBAFModule);
2132 m_hBAFModule = NULL;
2133 }
2134 }
2135 }
2136
2137
2204private: 2138private:
2205 // 2139 //
2206 // UiThreadProc - entrypoint for UI thread. 2140 // UiThreadProc - entrypoint for UI thread.
@@ -2214,6 +2148,7 @@ private:
2214 BOOL fComInitialized = FALSE; 2148 BOOL fComInitialized = FALSE;
2215 BOOL fRet = FALSE; 2149 BOOL fRet = FALSE;
2216 MSG msg = { }; 2150 MSG msg = { };
2151 DWORD dwQuit = 0;
2217 2152
2218 // Initialize COM and theme. 2153 // Initialize COM and theme.
2219 hr = ::CoInitialize(NULL); 2154 hr = ::CoInitialize(NULL);
@@ -2274,8 +2209,6 @@ private:
2274 pThis->DestroyMainWindow(); 2209 pThis->DestroyMainWindow();
2275 pThis->UninitializeTaskbarButton(); 2210 pThis->UninitializeTaskbarButton();
2276 2211
2277 // initiate engine shutdown
2278 DWORD dwQuit = HRESULT_CODE(hr);
2279 if (BOOTSTRAPPER_APPLY_RESTART_INITIATED == pThis->m_restartResult) 2212 if (BOOTSTRAPPER_APPLY_RESTART_INITIATED == pThis->m_restartResult)
2280 { 2213 {
2281 dwQuit = ERROR_SUCCESS_REBOOT_INITIATED; 2214 dwQuit = ERROR_SUCCESS_REBOOT_INITIATED;
@@ -2284,6 +2217,17 @@ private:
2284 { 2217 {
2285 dwQuit = ERROR_SUCCESS_REBOOT_REQUIRED; 2218 dwQuit = ERROR_SUCCESS_REBOOT_REQUIRED;
2286 } 2219 }
2220 else if (SEVERITY_ERROR == HRESULT_SEVERITY(hr) && FACILITY_WIN32 == HRESULT_FACILITY(hr))
2221 {
2222 // Convert Win32 HRESULTs back to the error code.
2223 dwQuit = HRESULT_CODE(hr);
2224 }
2225 else
2226 {
2227 dwQuit = hr;
2228 }
2229
2230 // initiate engine shutdown
2287 pThis->m_pEngine->Quit(dwQuit); 2231 pThis->m_pEngine->Quit(dwQuit);
2288 2232
2289 ReleaseTheme(pThis->m_pTheme); 2233 ReleaseTheme(pThis->m_pTheme);
@@ -2335,9 +2279,6 @@ private:
2335 GetBundleFileVersion(); 2279 GetBundleFileVersion();
2336 // don't fail if we couldn't get the version info; best-effort only 2280 // don't fail if we couldn't get the version info; best-effort only
2337 2281
2338 hr = InitializePackageInfo();
2339 BalExitOnFailure(hr, "Failed to initialize wixstdba package information.");
2340
2341 if (m_fPrereq) 2282 if (m_fPrereq)
2342 { 2283 {
2343 hr = InitializePrerequisiteInformation(); 2284 hr = InitializePrerequisiteInformation();
@@ -2521,38 +2462,6 @@ private:
2521 } 2462 }
2522 2463
2523 2464
2524 HRESULT InitializePackageInfo()
2525 {
2526 HRESULT hr = S_OK;
2527 BAL_INFO_PACKAGE* pPackage = NULL;
2528
2529 for (DWORD i = 0; i < m_Bundle.packages.cPackages; ++i)
2530 {
2531 pPackage = &m_Bundle.packages.rgPackages[i];
2532
2533 hr = InitializePackageInfoForPackage(pPackage);
2534 BalExitOnFailure(hr, "Failed to initialize wixstdba package info for package: %ls.", pPackage->sczId);
2535 }
2536
2537 LExit:
2538 return hr;
2539 }
2540
2541
2542 HRESULT InitializePackageInfoForPackage(
2543 __in BAL_INFO_PACKAGE* pPackage
2544 )
2545 {
2546 HRESULT hr = S_OK;
2547
2548 pPackage->pvCustomData = MemAlloc(sizeof(WIXSTDBA_PACKAGE_INFO), TRUE);
2549 BalExitOnNull(pPackage->pvCustomData, hr, E_OUTOFMEMORY, "Failed to allocate memory for wixstdba package info.");
2550
2551 LExit:
2552 return hr;
2553 }
2554
2555
2556 HRESULT InitializePrerequisiteInformation() 2465 HRESULT InitializePrerequisiteInformation()
2557 { 2466 {
2558 HRESULT hr = S_OK; 2467 HRESULT hr = S_OK;
@@ -2673,35 +2582,6 @@ private:
2673 return hr; 2582 return hr;
2674 } 2583 }
2675 2584
2676 HRESULT GetPackageInfo(
2677 __in_z LPCWSTR wzPackageId,
2678 __out WIXSTDBA_PACKAGE_INFO** ppPackageInfo,
2679 __out BAL_INFO_PACKAGE** ppPackage
2680 )
2681 {
2682 HRESULT hr = E_NOTFOUND;
2683 WIXSTDBA_PACKAGE_INFO* pPackageInfo = NULL;
2684 BAL_INFO_PACKAGE* pPackage = NULL;
2685
2686 Assert(wzPackageId && *wzPackageId);
2687 Assert(ppPackage);
2688 Assert(ppPackageInfo);
2689
2690 hr = BalInfoFindPackageById(&m_Bundle.packages, wzPackageId, &pPackage);
2691 if (E_NOTFOUND != hr)
2692 {
2693 ExitOnFailure(hr, "Failed trying to find the requested package.");
2694
2695 pPackageInfo = reinterpret_cast<WIXSTDBA_PACKAGE_INFO*>(pPackage->pvCustomData);
2696 }
2697
2698 *ppPackageInfo = pPackageInfo;
2699 *ppPackage = pPackage;
2700
2701 LExit:
2702 return hr;
2703 }
2704
2705 2585
2706 // 2586 //
2707 // Get the file version of the bootstrapper and record in bootstrapper log file 2587 // Get the file version of the bootstrapper and record in bootstrapper log file
@@ -3408,6 +3288,23 @@ private:
3408 } 3288 }
3409 } 3289 }
3410 } 3290 }
3291 else if (E_PREREQBA_INFINITE_LOOP == m_hrFinal)
3292 {
3293 HRESULT hr = StrAllocString(&sczUnformattedText, L"#(loc.PREREQBAINFINITELOOPErrorMessage)", 0);
3294 if (FAILED(hr))
3295 {
3296 BalLogError(hr, "Failed to initialize PREREQBAINFINITELOOPErrorMessage loc identifier.");
3297 }
3298 else
3299 {
3300 hr = LocLocalizeString(m_pWixLoc, &sczUnformattedText);
3301 if (FAILED(hr))
3302 {
3303 BalLogError(hr, "Failed to localize PREREQBAINFINITELOOPErrorMessage: %ls", sczUnformattedText);
3304 ReleaseNullStr(sczUnformattedText);
3305 }
3306 }
3307 }
3411 else // try to get the error message from the error code. 3308 else // try to get the error message from the error code.
3412 { 3309 {
3413 StrAllocFromError(&sczUnformattedText, m_hrFinal, NULL); 3310 StrAllocFromError(&sczUnformattedText, m_hrFinal, NULL);
@@ -3424,14 +3321,9 @@ private:
3424 StrAllocString(&sczText, sczUnformattedText, 0); 3321 StrAllocString(&sczText, sczUnformattedText, 0);
3425 } 3322 }
3426 } 3323 }
3427 else if (E_MBAHOST_NET452_ON_WIN7RTM == m_hrFinal) 3324 else if (E_MBAHOST_NET452_ON_WIN7RTM == m_hrFinal ||
3428 { 3325 E_DNCHOST_SCD_RUNTIME_FAILURE == m_hrFinal ||
3429 if (sczUnformattedText) 3326 E_PREREQBA_INFINITE_LOOP == m_hrFinal)
3430 {
3431 BalFormatString(sczUnformattedText, &sczText);
3432 }
3433 }
3434 else if (E_DNCHOST_SCD_RUNTIME_FAILURE == m_hrFinal)
3435 { 3327 {
3436 if (sczUnformattedText) 3328 if (sczUnformattedText)
3437 { 3329 {
@@ -4180,8 +4072,7 @@ public:
4180 // 4072 //
4181 CWixStandardBootstrapperApplication( 4073 CWixStandardBootstrapperApplication(
4182 __in HMODULE hModule, 4074 __in HMODULE hModule,
4183 __in BOOL fPrereq, 4075 __in_opt PREQBA_DATA* pPrereqData,
4184 __in HRESULT hrHostInitialization,
4185 __in IBootstrapperEngine* pEngine 4076 __in IBootstrapperEngine* pEngine
4186 ) : CBalBaseBootstrapperApplication(pEngine, 3, 3000) 4077 ) : CBalBaseBootstrapperApplication(pEngine, 3, 3000)
4187 { 4078 {
@@ -4210,7 +4101,7 @@ public:
4210 m_hWnd = NULL; 4101 m_hWnd = NULL;
4211 4102
4212 m_state = WIXSTDBA_STATE_INITIALIZING; 4103 m_state = WIXSTDBA_STATE_INITIALIZING;
4213 m_hrFinal = hrHostInitialization; 4104 m_hrFinal = pPrereqData ? pPrereqData->hrHostInitialization : S_OK;
4214 4105
4215 m_restartResult = BOOTSTRAPPER_APPLY_RESTART_NONE; 4106 m_restartResult = BOOTSTRAPPER_APPLY_RESTART_NONE;
4216 m_fRestartRequired = FALSE; 4107 m_fRestartRequired = FALSE;
@@ -4231,9 +4122,9 @@ public:
4231 m_fShowingInternalUiThisPackage = FALSE; 4122 m_fShowingInternalUiThisPackage = FALSE;
4232 m_fTriedToLaunchElevated = FALSE; 4123 m_fTriedToLaunchElevated = FALSE;
4233 4124
4234 m_fPrereq = fPrereq; 4125 m_pPrereqData = pPrereqData;
4126 m_fPrereq = NULL != pPrereqData;
4235 m_fPrereqInstalled = FALSE; 4127 m_fPrereqInstalled = FALSE;
4236 m_fPrereqAlreadyInstalled = FALSE;
4237 4128
4238 pEngine->AddRef(); 4129 pEngine->AddRef();
4239 m_pEngine = pEngine; 4130 m_pEngine = pEngine;
@@ -4418,11 +4309,6 @@ public:
4418 AssertSz(!m_pTaskbarList, "Taskbar should have been released before destructor."); 4309 AssertSz(!m_pTaskbarList, "Taskbar should have been released before destructor.");
4419 AssertSz(!m_pTheme, "Theme should have been released before destructor."); 4310 AssertSz(!m_pTheme, "Theme should have been released before destructor.");
4420 4311
4421 for (DWORD i = 0; i < m_Bundle.packages.cPackages; ++i)
4422 {
4423 ReleaseMem(m_Bundle.packages.rgPackages[i].pvCustomData);
4424 }
4425
4426 ::DeleteCriticalSection(&m_csShowingInternalUiThisPackage); 4312 ::DeleteCriticalSection(&m_csShowingInternalUiThisPackage);
4427 ReleaseStr(m_sczFailedMessage); 4313 ReleaseStr(m_sczFailedMessage);
4428 ReleaseStr(m_sczConfirmCloseMessage); 4314 ReleaseStr(m_sczConfirmCloseMessage);
@@ -4436,18 +4322,6 @@ public:
4436 ReleaseStr(m_sczBundleVersion); 4322 ReleaseStr(m_sczBundleVersion);
4437 ReleaseStr(m_sczAfterForcedRestartPackage); 4323 ReleaseStr(m_sczAfterForcedRestartPackage);
4438 ReleaseNullObject(m_pEngine); 4324 ReleaseNullObject(m_pEngine);
4439
4440 if (m_hBAFModule)
4441 {
4442 PFN_BA_FUNCTIONS_DESTROY pfnBAFunctionsDestroy = reinterpret_cast<PFN_BA_FUNCTIONS_DESTROY>(::GetProcAddress(m_hBAFModule, "BAFunctionsDestroy"));
4443 if (pfnBAFunctionsDestroy)
4444 {
4445 pfnBAFunctionsDestroy();
4446 }
4447
4448 ::FreeLibrary(m_hBAFModule);
4449 m_hBAFModule = NULL;
4450 }
4451 } 4325 }
4452 4326
4453private: 4327private:
@@ -4529,9 +4403,9 @@ private:
4529 BOOL m_fSupportCacheOnly; 4403 BOOL m_fSupportCacheOnly;
4530 BOOL m_fRequestedCacheOnly; 4404 BOOL m_fRequestedCacheOnly;
4531 4405
4406 PREQBA_DATA* m_pPrereqData;
4532 BOOL m_fPrereq; 4407 BOOL m_fPrereq;
4533 BOOL m_fPrereqInstalled; 4408 BOOL m_fPrereqInstalled;
4534 BOOL m_fPrereqAlreadyInstalled;
4535 4409
4536 ITaskbarList3* m_pTaskbarList; 4410 ITaskbarList3* m_pTaskbarList;
4537 UINT m_uTaskbarButtonCreatedMessage; 4411 UINT m_uTaskbarButtonCreatedMessage;
@@ -4551,8 +4425,7 @@ private:
4551// 4425//
4552HRESULT CreateBootstrapperApplication( 4426HRESULT CreateBootstrapperApplication(
4553 __in HMODULE hModule, 4427 __in HMODULE hModule,
4554 __in BOOL fPrereq, 4428 __in_opt PREQBA_DATA* pPrereqData,
4555 __in HRESULT hrHostInitialization,
4556 __in IBootstrapperEngine* pEngine, 4429 __in IBootstrapperEngine* pEngine,
4557 __in const BOOTSTRAPPER_CREATE_ARGS* pArgs, 4430 __in const BOOTSTRAPPER_CREATE_ARGS* pArgs,
4558 __inout BOOTSTRAPPER_CREATE_RESULTS* pResults, 4431 __inout BOOTSTRAPPER_CREATE_RESULTS* pResults,
@@ -4567,7 +4440,7 @@ HRESULT CreateBootstrapperApplication(
4567 BalExitOnFailure(hr = E_INVALIDARG, "Engine requested Unknown display type."); 4440 BalExitOnFailure(hr = E_INVALIDARG, "Engine requested Unknown display type.");
4568 } 4441 }
4569 4442
4570 pApplication = new CWixStandardBootstrapperApplication(hModule, fPrereq, hrHostInitialization, pEngine); 4443 pApplication = new CWixStandardBootstrapperApplication(hModule, pPrereqData, pEngine);
4571 BalExitOnNull(pApplication, hr, E_OUTOFMEMORY, "Failed to create new standard bootstrapper application object."); 4444 BalExitOnNull(pApplication, hr, E_OUTOFMEMORY, "Failed to create new standard bootstrapper application object.");
4572 4445
4573 hr = pApplication->Initialize(pArgs); 4446 hr = pApplication->Initialize(pArgs);
@@ -4584,6 +4457,17 @@ LExit:
4584} 4457}
4585 4458
4586 4459
4460void DestroyBootstrapperApplication(
4461 __in IBootstrapperApplication* pApplication,
4462 __in const BOOTSTRAPPER_DESTROY_ARGS* pArgs,
4463 __inout BOOTSTRAPPER_DESTROY_RESULTS* pResults
4464 )
4465{
4466 CWixStandardBootstrapperApplication* pBA = (CWixStandardBootstrapperApplication*)pApplication;
4467 pBA->Uninitialize(pArgs, pResults);
4468}
4469
4470
4587static HRESULT DAPI EvaluateVariableConditionCallback( 4471static HRESULT DAPI EvaluateVariableConditionCallback(
4588 __in_z LPCWSTR wzCondition, 4472 __in_z LPCWSTR wzCondition,
4589 __out BOOL* pf, 4473 __out BOOL* pf,