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); |