diff options
Diffstat (limited to 'src/burn/engine/plan.cpp')
| -rw-r--r-- | src/burn/engine/plan.cpp | 143 |
1 files changed, 130 insertions, 13 deletions
diff --git a/src/burn/engine/plan.cpp b/src/burn/engine/plan.cpp index f850d49c..f1fb87b8 100644 --- a/src/burn/engine/plan.cpp +++ b/src/burn/engine/plan.cpp | |||
| @@ -103,6 +103,10 @@ static HRESULT AppendCleanAction( | |||
| 103 | __in BURN_PLAN* pPlan, | 103 | __in BURN_PLAN* pPlan, |
| 104 | __out BURN_CLEAN_ACTION** ppCleanAction | 104 | __out BURN_CLEAN_ACTION** ppCleanAction |
| 105 | ); | 105 | ); |
| 106 | static HRESULT AppendRestoreRelatedBundleAction( | ||
| 107 | __in BURN_PLAN* pPlan, | ||
| 108 | __out BURN_EXECUTE_ACTION** ppExecuteAction | ||
| 109 | ); | ||
| 106 | static HRESULT ProcessPayloadGroup( | 110 | static HRESULT ProcessPayloadGroup( |
| 107 | __in BURN_PLAN* pPlan, | 111 | __in BURN_PLAN* pPlan, |
| 108 | __in BURN_PAYLOAD_GROUP* pPayloadGroup | 112 | __in BURN_PAYLOAD_GROUP* pPayloadGroup |
| @@ -196,6 +200,15 @@ extern "C" void PlanReset( | |||
| 196 | MemFree(pPlan->rgRollbackActions); | 200 | MemFree(pPlan->rgRollbackActions); |
| 197 | } | 201 | } |
| 198 | 202 | ||
| 203 | if (pPlan->rgRestoreRelatedBundleActions) | ||
| 204 | { | ||
| 205 | for (DWORD i = 0; i < pPlan->cRestoreRelatedBundleActions; ++i) | ||
| 206 | { | ||
| 207 | PlanUninitializeExecuteAction(&pPlan->rgRestoreRelatedBundleActions[i]); | ||
| 208 | } | ||
| 209 | MemFree(pPlan->rgRestoreRelatedBundleActions); | ||
| 210 | } | ||
| 211 | |||
| 199 | if (pPlan->rgCleanActions) | 212 | if (pPlan->rgCleanActions) |
| 200 | { | 213 | { |
| 201 | // Nothing needs to be freed inside clean actions today. | 214 | // Nothing needs to be freed inside clean actions today. |
| @@ -1276,6 +1289,9 @@ extern "C" HRESULT PlanRelatedBundlesBegin( | |||
| 1276 | continue; | 1289 | continue; |
| 1277 | } | 1290 | } |
| 1278 | 1291 | ||
| 1292 | pRelatedBundle->defaultRequestedRestore = BOOTSTRAPPER_REQUEST_STATE_NONE; | ||
| 1293 | pRelatedBundle->requestedRestore = BOOTSTRAPPER_REQUEST_STATE_NONE; | ||
| 1294 | pRelatedBundle->restore = BOOTSTRAPPER_ACTION_STATE_NONE; | ||
| 1279 | pRelatedBundle->package.defaultRequested = BOOTSTRAPPER_REQUEST_STATE_NONE; | 1295 | pRelatedBundle->package.defaultRequested = BOOTSTRAPPER_REQUEST_STATE_NONE; |
| 1280 | pRelatedBundle->package.requested = BOOTSTRAPPER_REQUEST_STATE_NONE; | 1296 | pRelatedBundle->package.requested = BOOTSTRAPPER_REQUEST_STATE_NONE; |
| 1281 | 1297 | ||
| @@ -1312,12 +1328,6 @@ extern "C" HRESULT PlanRelatedBundlesBegin( | |||
| 1312 | hr = UserExperienceOnPlanRelatedBundle(pUserExperience, pRelatedBundle->package.sczId, &pRelatedBundle->package.requested); | 1328 | hr = UserExperienceOnPlanRelatedBundle(pUserExperience, pRelatedBundle->package.sczId, &pRelatedBundle->package.requested); |
| 1313 | ExitOnRootFailure(hr, "BA aborted plan related bundle."); | 1329 | ExitOnRootFailure(hr, "BA aborted plan related bundle."); |
| 1314 | 1330 | ||
| 1315 | // Log when the BA changed the bundle state so the engine doesn't get blamed for planning the wrong thing. | ||
| 1316 | if (pRelatedBundle->package.requested != pRelatedBundle->package.defaultRequested) | ||
| 1317 | { | ||
| 1318 | LogId(REPORT_STANDARD, MSG_PLANNED_BUNDLE_UX_CHANGED_REQUEST, pRelatedBundle->package.sczId, LoggingRequestStateToString(pRelatedBundle->package.requested), LoggingRequestStateToString(pRelatedBundle->package.defaultRequested)); | ||
| 1319 | } | ||
| 1320 | |||
| 1321 | // If uninstalling and the dependent related bundle may be executed, ignore its provider key to allow for downgrades with ref-counting. | 1331 | // If uninstalling and the dependent related bundle may be executed, ignore its provider key to allow for downgrades with ref-counting. |
| 1322 | if (BOOTSTRAPPER_ACTION_UNINSTALL == pPlan->action && BOOTSTRAPPER_RELATION_DEPENDENT == pRelatedBundle->relationType && BOOTSTRAPPER_REQUEST_STATE_NONE != pRelatedBundle->package.requested) | 1332 | if (BOOTSTRAPPER_ACTION_UNINSTALL == pPlan->action && BOOTSTRAPPER_RELATION_DEPENDENT == pRelatedBundle->relationType && BOOTSTRAPPER_REQUEST_STATE_NONE != pRelatedBundle->package.requested) |
| 1323 | { | 1333 | { |
| @@ -1340,6 +1350,7 @@ LExit: | |||
| 1340 | } | 1350 | } |
| 1341 | 1351 | ||
| 1342 | extern "C" HRESULT PlanRelatedBundlesComplete( | 1352 | extern "C" HRESULT PlanRelatedBundlesComplete( |
| 1353 | __in BURN_USER_EXPERIENCE* pUserExperience, | ||
| 1343 | __in BURN_REGISTRATION* pRegistration, | 1354 | __in BURN_REGISTRATION* pRegistration, |
| 1344 | __in BURN_PLAN* pPlan, | 1355 | __in BURN_PLAN* pPlan, |
| 1345 | __in BURN_LOGGING* pLog, | 1356 | __in BURN_LOGGING* pLog, |
| @@ -1359,16 +1370,19 @@ extern "C" HRESULT PlanRelatedBundlesComplete( | |||
| 1359 | ExitOnFailure(hr, "Failed to create dictionary for planned packages."); | 1370 | ExitOnFailure(hr, "Failed to create dictionary for planned packages."); |
| 1360 | 1371 | ||
| 1361 | BOOL fExecutingAnyPackage = FALSE; | 1372 | BOOL fExecutingAnyPackage = FALSE; |
| 1373 | BOOL fInstallingAnyPackage = FALSE; | ||
| 1362 | 1374 | ||
| 1363 | for (DWORD i = 0; i < pPlan->cExecuteActions; ++i) | 1375 | for (DWORD i = 0; i < pPlan->cExecuteActions; ++i) |
| 1364 | { | 1376 | { |
| 1377 | BOOTSTRAPPER_ACTION_STATE packageAction = BOOTSTRAPPER_ACTION_STATE_NONE; | ||
| 1378 | |||
| 1365 | switch (pPlan->rgExecuteActions[i].type) | 1379 | switch (pPlan->rgExecuteActions[i].type) |
| 1366 | { | 1380 | { |
| 1367 | case BURN_EXECUTE_ACTION_TYPE_RELATED_BUNDLE: | 1381 | case BURN_EXECUTE_ACTION_TYPE_RELATED_BUNDLE: |
| 1368 | if (BOOTSTRAPPER_ACTION_STATE_NONE != pPlan->rgExecuteActions[i].relatedBundle.action) | 1382 | packageAction = pPlan->rgExecuteActions[i].relatedBundle.action; |
| 1369 | { | ||
| 1370 | fExecutingAnyPackage = TRUE; | ||
| 1371 | 1383 | ||
| 1384 | if (BOOTSTRAPPER_ACTION_STATE_NONE != packageAction) | ||
| 1385 | { | ||
| 1372 | BURN_PACKAGE* pPackage = &pPlan->rgExecuteActions[i].relatedBundle.pRelatedBundle->package; | 1386 | BURN_PACKAGE* pPackage = &pPlan->rgExecuteActions[i].relatedBundle.pRelatedBundle->package; |
| 1373 | if (pPackage->cDependencyProviders) | 1387 | if (pPackage->cDependencyProviders) |
| 1374 | { | 1388 | { |
| @@ -1380,21 +1394,24 @@ extern "C" HRESULT PlanRelatedBundlesComplete( | |||
| 1380 | break; | 1394 | break; |
| 1381 | 1395 | ||
| 1382 | case BURN_EXECUTE_ACTION_TYPE_EXE_PACKAGE: | 1396 | case BURN_EXECUTE_ACTION_TYPE_EXE_PACKAGE: |
| 1383 | fExecutingAnyPackage |= (BOOTSTRAPPER_ACTION_STATE_NONE != pPlan->rgExecuteActions[i].exePackage.action); | 1397 | packageAction = pPlan->rgExecuteActions[i].exePackage.action; |
| 1384 | break; | 1398 | break; |
| 1385 | 1399 | ||
| 1386 | case BURN_EXECUTE_ACTION_TYPE_MSI_PACKAGE: | 1400 | case BURN_EXECUTE_ACTION_TYPE_MSI_PACKAGE: |
| 1387 | fExecutingAnyPackage |= (BOOTSTRAPPER_ACTION_STATE_NONE != pPlan->rgExecuteActions[i].msiPackage.action); | 1401 | packageAction = pPlan->rgExecuteActions[i].msiPackage.action; |
| 1388 | break; | 1402 | break; |
| 1389 | 1403 | ||
| 1390 | case BURN_EXECUTE_ACTION_TYPE_MSP_TARGET: | 1404 | case BURN_EXECUTE_ACTION_TYPE_MSP_TARGET: |
| 1391 | fExecutingAnyPackage |= (BOOTSTRAPPER_ACTION_STATE_NONE != pPlan->rgExecuteActions[i].mspTarget.action); | 1405 | packageAction = pPlan->rgExecuteActions[i].mspTarget.action; |
| 1392 | break; | 1406 | break; |
| 1393 | 1407 | ||
| 1394 | case BURN_EXECUTE_ACTION_TYPE_MSU_PACKAGE: | 1408 | case BURN_EXECUTE_ACTION_TYPE_MSU_PACKAGE: |
| 1395 | fExecutingAnyPackage |= (BOOTSTRAPPER_ACTION_STATE_NONE != pPlan->rgExecuteActions[i].msuPackage.action); | 1409 | packageAction = pPlan->rgExecuteActions[i].msuPackage.action; |
| 1396 | break; | 1410 | break; |
| 1397 | } | 1411 | } |
| 1412 | |||
| 1413 | fExecutingAnyPackage |= BOOTSTRAPPER_ACTION_STATE_NONE != packageAction; | ||
| 1414 | fInstallingAnyPackage |= BOOTSTRAPPER_ACTION_STATE_INSTALL == packageAction || BOOTSTRAPPER_ACTION_STATE_MINOR_UPGRADE == packageAction; | ||
| 1398 | } | 1415 | } |
| 1399 | 1416 | ||
| 1400 | for (DWORD i = 0; i < pRegistration->relatedBundles.cRelatedBundles; ++i) | 1417 | for (DWORD i = 0; i < pRegistration->relatedBundles.cRelatedBundles; ++i) |
| @@ -1492,6 +1509,62 @@ extern "C" HRESULT PlanRelatedBundlesComplete( | |||
| 1492 | hr = DependencyPlanPackageComplete(&pRelatedBundle->package, pPlan); | 1509 | hr = DependencyPlanPackageComplete(&pRelatedBundle->package, pPlan); |
| 1493 | ExitOnFailure(hr, "Failed to complete plan dependency actions for related bundle package: %ls", pRelatedBundle->package.sczId); | 1510 | ExitOnFailure(hr, "Failed to complete plan dependency actions for related bundle package: %ls", pRelatedBundle->package.sczId); |
| 1494 | } | 1511 | } |
| 1512 | |||
| 1513 | if (fInstallingAnyPackage && BOOTSTRAPPER_RELATION_UPGRADE == pRelatedBundle->relationType) | ||
| 1514 | { | ||
| 1515 | BURN_EXECUTE_ACTION* pAction = NULL; | ||
| 1516 | |||
| 1517 | pRelatedBundle->defaultRequestedRestore = pRelatedBundle->requestedRestore = BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT; | ||
| 1518 | |||
| 1519 | hr = UserExperienceOnPlanRestoreRelatedBundle(pUserExperience, pRelatedBundle->package.sczId, &pRelatedBundle->requestedRestore); | ||
| 1520 | ExitOnRootFailure(hr, "BA aborted plan restore related bundle."); | ||
| 1521 | |||
| 1522 | switch (pRelatedBundle->requestedRestore) | ||
| 1523 | { | ||
| 1524 | case BOOTSTRAPPER_REQUEST_STATE_REPAIR: | ||
| 1525 | pRelatedBundle->restore = BOOTSTRAPPER_ACTION_STATE_REPAIR; | ||
| 1526 | break; | ||
| 1527 | case BOOTSTRAPPER_REQUEST_STATE_ABSENT: __fallthrough; | ||
| 1528 | case BOOTSTRAPPER_REQUEST_STATE_CACHE: __fallthrough; | ||
| 1529 | case BOOTSTRAPPER_REQUEST_STATE_FORCE_ABSENT: | ||
| 1530 | pRelatedBundle->restore = BOOTSTRAPPER_ACTION_STATE_UNINSTALL; | ||
| 1531 | break; | ||
| 1532 | case BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT: | ||
| 1533 | pRelatedBundle->restore = BOOTSTRAPPER_ACTION_STATE_INSTALL; | ||
| 1534 | break; | ||
| 1535 | default: | ||
| 1536 | pRelatedBundle->restore = BOOTSTRAPPER_ACTION_STATE_NONE; | ||
| 1537 | break; | ||
| 1538 | } | ||
| 1539 | |||
| 1540 | if (BOOTSTRAPPER_ACTION_STATE_NONE != pRelatedBundle->restore) | ||
| 1541 | { | ||
| 1542 | hr = AppendRestoreRelatedBundleAction(pPlan, &pAction); | ||
| 1543 | ExitOnFailure(hr, "Failed to append restore related bundle action to plan."); | ||
| 1544 | |||
| 1545 | pAction->type = BURN_EXECUTE_ACTION_TYPE_RELATED_BUNDLE; | ||
| 1546 | pAction->relatedBundle.pRelatedBundle = pRelatedBundle; | ||
| 1547 | pAction->relatedBundle.action = pRelatedBundle->restore; | ||
| 1548 | |||
| 1549 | if (pRelatedBundle->package.Bundle.sczIgnoreDependencies) | ||
| 1550 | { | ||
| 1551 | hr = StrAllocString(&pAction->relatedBundle.sczIgnoreDependencies, pRelatedBundle->package.Bundle.sczIgnoreDependencies, 0); | ||
| 1552 | ExitOnFailure(hr, "Failed to allocate the list of dependencies to ignore."); | ||
| 1553 | } | ||
| 1554 | |||
| 1555 | if (pRelatedBundle->package.Bundle.wzAncestors) | ||
| 1556 | { | ||
| 1557 | hr = StrAllocString(&pAction->relatedBundle.sczAncestors, pRelatedBundle->package.Bundle.wzAncestors, 0); | ||
| 1558 | ExitOnFailure(hr, "Failed to allocate the list of ancestors."); | ||
| 1559 | } | ||
| 1560 | |||
| 1561 | if (pRelatedBundle->package.Bundle.wzEngineWorkingDirectory) | ||
| 1562 | { | ||
| 1563 | hr = StrAllocString(&pAction->relatedBundle.sczEngineWorkingDirectory, pRelatedBundle->package.Bundle.wzEngineWorkingDirectory, 0); | ||
| 1564 | ExitOnFailure(hr, "Failed to allocate the custom working directory."); | ||
| 1565 | } | ||
| 1566 | } | ||
| 1567 | } | ||
| 1495 | } | 1568 | } |
| 1496 | 1569 | ||
| 1497 | LExit: | 1570 | LExit: |
| @@ -2269,6 +2342,23 @@ LExit: | |||
| 2269 | return hr; | 2342 | return hr; |
| 2270 | } | 2343 | } |
| 2271 | 2344 | ||
| 2345 | static HRESULT AppendRestoreRelatedBundleAction( | ||
| 2346 | __in BURN_PLAN* pPlan, | ||
| 2347 | __out BURN_EXECUTE_ACTION** ppExecuteAction | ||
| 2348 | ) | ||
| 2349 | { | ||
| 2350 | HRESULT hr = S_OK; | ||
| 2351 | |||
| 2352 | hr = MemEnsureArraySizeForNewItems(reinterpret_cast<LPVOID*>(&pPlan->rgRestoreRelatedBundleActions), pPlan->cRestoreRelatedBundleActions, 1, sizeof(BURN_EXECUTE_ACTION), 5); | ||
| 2353 | ExitOnFailure(hr, "Failed to grow plan's array of restore related bundle actions."); | ||
| 2354 | |||
| 2355 | *ppExecuteAction = pPlan->rgRestoreRelatedBundleActions + pPlan->cRestoreRelatedBundleActions; | ||
| 2356 | ++pPlan->cRestoreRelatedBundleActions; | ||
| 2357 | |||
| 2358 | LExit: | ||
| 2359 | return hr; | ||
| 2360 | } | ||
| 2361 | |||
| 2272 | static HRESULT ProcessPayloadGroup( | 2362 | static HRESULT ProcessPayloadGroup( |
| 2273 | __in BURN_PLAN* pPlan, | 2363 | __in BURN_PLAN* pPlan, |
| 2274 | __in BURN_PAYLOAD_GROUP* pPayloadGroup | 2364 | __in BURN_PAYLOAD_GROUP* pPayloadGroup |
| @@ -2725,6 +2815,28 @@ static void ExecuteActionLog( | |||
| 2725 | } | 2815 | } |
| 2726 | } | 2816 | } |
| 2727 | 2817 | ||
| 2818 | static void RestoreRelatedBundleActionLog( | ||
| 2819 | __in DWORD iAction, | ||
| 2820 | __in BURN_EXECUTE_ACTION* pAction | ||
| 2821 | ) | ||
| 2822 | { | ||
| 2823 | switch (pAction->type) | ||
| 2824 | { | ||
| 2825 | case BURN_EXECUTE_ACTION_TYPE_RELATED_BUNDLE: | ||
| 2826 | LogStringLine(PlanDumpLevel, "Restore action[%u]: RELATED_BUNDLE package id: %ls, action: %hs, ignore dependencies: %ls", iAction, pAction->relatedBundle.pRelatedBundle->package.sczId, LoggingActionStateToString(pAction->relatedBundle.action), pAction->relatedBundle.sczIgnoreDependencies); | ||
| 2827 | break; | ||
| 2828 | |||
| 2829 | default: | ||
| 2830 | AssertSz(FALSE, "Unknown execute action type."); | ||
| 2831 | break; | ||
| 2832 | } | ||
| 2833 | |||
| 2834 | if (pAction->fDeleted) | ||
| 2835 | { | ||
| 2836 | LogStringLine(PlanDumpLevel, " (deleted action)"); | ||
| 2837 | } | ||
| 2838 | } | ||
| 2839 | |||
| 2728 | static void CleanActionLog( | 2840 | static void CleanActionLog( |
| 2729 | __in DWORD iAction, | 2841 | __in DWORD iAction, |
| 2730 | __in BURN_CLEAN_ACTION* pAction | 2842 | __in BURN_CLEAN_ACTION* pAction |
| @@ -2784,6 +2896,11 @@ extern "C" void PlanDump( | |||
| 2784 | ExecuteActionLog(i, pPlan->rgRollbackActions + i, TRUE); | 2896 | ExecuteActionLog(i, pPlan->rgRollbackActions + i, TRUE); |
| 2785 | } | 2897 | } |
| 2786 | 2898 | ||
| 2899 | for (DWORD i = 0; i < pPlan->cRestoreRelatedBundleActions; ++i) | ||
| 2900 | { | ||
| 2901 | RestoreRelatedBundleActionLog(i, pPlan->rgRestoreRelatedBundleActions + i); | ||
| 2902 | } | ||
| 2903 | |||
| 2787 | for (DWORD i = 0; i < pPlan->cCleanActions; ++i) | 2904 | for (DWORD i = 0; i < pPlan->cCleanActions; ++i) |
| 2788 | { | 2905 | { |
| 2789 | CleanActionLog(i, pPlan->rgCleanActions + i); | 2906 | CleanActionLog(i, pPlan->rgCleanActions + i); |
