diff options
Diffstat (limited to 'src/burn/engine')
-rw-r--r-- | src/burn/engine/bundlepackageengine.cpp | 29 | ||||
-rw-r--r-- | src/burn/engine/core.cpp | 16 | ||||
-rw-r--r-- | src/burn/engine/detect.cpp | 18 | ||||
-rw-r--r-- | src/burn/engine/elevation.cpp | 9 | ||||
-rw-r--r-- | src/burn/engine/engine.mc | 10 | ||||
-rw-r--r-- | src/burn/engine/logging.cpp | 31 | ||||
-rw-r--r-- | src/burn/engine/logging.h | 4 | ||||
-rw-r--r-- | src/burn/engine/plan.cpp | 161 | ||||
-rw-r--r-- | src/burn/engine/plan.h | 16 | ||||
-rw-r--r-- | src/burn/engine/registration.cpp | 23 | ||||
-rw-r--r-- | src/burn/engine/registration.h | 8 | ||||
-rw-r--r-- | src/burn/engine/relatedbundle.cpp | 105 | ||||
-rw-r--r-- | src/burn/engine/relatedbundle.h | 5 | ||||
-rw-r--r-- | src/burn/engine/userexperience.cpp | 32 | ||||
-rw-r--r-- | src/burn/engine/userexperience.h | 5 |
15 files changed, 396 insertions, 76 deletions
diff --git a/src/burn/engine/bundlepackageengine.cpp b/src/burn/engine/bundlepackageengine.cpp index b5fc51e5..88a00f5e 100644 --- a/src/burn/engine/bundlepackageengine.cpp +++ b/src/burn/engine/bundlepackageengine.cpp | |||
@@ -2,7 +2,9 @@ | |||
2 | 2 | ||
3 | #include "precomp.h" | 3 | #include "precomp.h" |
4 | 4 | ||
5 | 5 | static BOOTSTRAPPER_RELATION_TYPE ConvertRelationType( | |
6 | __in BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE relationType | ||
7 | ); | ||
6 | 8 | ||
7 | // function definitions | 9 | // function definitions |
8 | 10 | ||
@@ -265,7 +267,7 @@ extern "C" HRESULT BundlePackageEngineExecuteRelatedBundle( | |||
265 | GENERIC_EXECUTE_MESSAGE message = { }; | 267 | GENERIC_EXECUTE_MESSAGE message = { }; |
266 | BOOTSTRAPPER_ACTION_STATE action = pExecuteAction->relatedBundle.action; | 268 | BOOTSTRAPPER_ACTION_STATE action = pExecuteAction->relatedBundle.action; |
267 | BURN_RELATED_BUNDLE* pRelatedBundle = pExecuteAction->relatedBundle.pRelatedBundle; | 269 | BURN_RELATED_BUNDLE* pRelatedBundle = pExecuteAction->relatedBundle.pRelatedBundle; |
268 | BOOTSTRAPPER_RELATION_TYPE relationType = pRelatedBundle->relationType; | 270 | BOOTSTRAPPER_RELATION_TYPE relationType = ConvertRelationType(pRelatedBundle->planRelationType); |
269 | BURN_PACKAGE* pPackage = &pRelatedBundle->package; | 271 | BURN_PACKAGE* pPackage = &pRelatedBundle->package; |
270 | BURN_PAYLOAD* pPackagePayload = pPackage->payloads.rgItems[0].pPayload; | 272 | BURN_PAYLOAD* pPackagePayload = pPackage->payloads.rgItems[0].pPayload; |
271 | LPCWSTR wzRelationTypeCommandLine = CoreRelationTypeToCommandLineString(relationType); | 273 | LPCWSTR wzRelationTypeCommandLine = CoreRelationTypeToCommandLineString(relationType); |
@@ -467,3 +469,26 @@ LExit: | |||
467 | 469 | ||
468 | return hr; | 470 | return hr; |
469 | } | 471 | } |
472 | |||
473 | static BOOTSTRAPPER_RELATION_TYPE ConvertRelationType( | ||
474 | __in BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE relationType | ||
475 | ) | ||
476 | { | ||
477 | switch (relationType) | ||
478 | { | ||
479 | case BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_DOWNGRADE: __fallthrough; | ||
480 | case BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_UPGRADE: | ||
481 | return BOOTSTRAPPER_RELATION_UPGRADE; | ||
482 | case BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_ADDON: | ||
483 | return BOOTSTRAPPER_RELATION_ADDON; | ||
484 | case BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_PATCH: | ||
485 | return BOOTSTRAPPER_RELATION_PATCH; | ||
486 | case BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_DEPENDENT_ADDON: | ||
487 | return BOOTSTRAPPER_RELATION_DEPENDENT_ADDON; | ||
488 | case BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_DEPENDENT_PATCH: | ||
489 | return BOOTSTRAPPER_RELATION_DEPENDENT_PATCH; | ||
490 | default: | ||
491 | AssertSz(BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_NONE == relationType, "Unknown BUNDLE_RELATION_TYPE"); | ||
492 | return BOOTSTRAPPER_RELATION_NONE; | ||
493 | } | ||
494 | } | ||
diff --git a/src/burn/engine/core.cpp b/src/burn/engine/core.cpp index 43f79133..9d4ea43e 100644 --- a/src/burn/engine/core.cpp +++ b/src/burn/engine/core.cpp | |||
@@ -449,11 +449,11 @@ extern "C" HRESULT CorePlan( | |||
449 | 449 | ||
450 | if (!pEngineState->fDetected) | 450 | if (!pEngineState->fDetected) |
451 | { | 451 | { |
452 | ExitOnFailure(hr = E_INVALIDSTATE, "Plan cannot be done without a successful Detect."); | 452 | ExitWithRootFailure(hr, E_INVALIDSTATE, "Plan cannot be done without a successful Detect."); |
453 | } | 453 | } |
454 | else if (pEngineState->plan.fAffectedMachineState) | 454 | else if (pEngineState->plan.fAffectedMachineState) |
455 | { | 455 | { |
456 | ExitOnFailure(hr = E_INVALIDSTATE, "Plan requires a new successful Detect after calling Apply."); | 456 | ExitWithRootFailure(hr, E_INVALIDSTATE, "Plan requires a new successful Detect after calling Apply."); |
457 | } | 457 | } |
458 | 458 | ||
459 | // Always reset the plan. | 459 | // Always reset the plan. |
@@ -482,6 +482,9 @@ extern "C" HRESULT CorePlan( | |||
482 | hr = DependencyPlanInitialize(&pEngineState->dependencies, &pEngineState->plan); | 482 | hr = DependencyPlanInitialize(&pEngineState->dependencies, &pEngineState->plan); |
483 | ExitOnFailure(hr, "Failed to initialize the dependencies for the plan."); | 483 | ExitOnFailure(hr, "Failed to initialize the dependencies for the plan."); |
484 | 484 | ||
485 | hr = RegistrationPlanInitialize(&pEngineState->registration); | ||
486 | ExitOnFailure(hr, "Failed to initialize registration for the plan."); | ||
487 | |||
485 | if (BOOTSTRAPPER_ACTION_LAYOUT == action) | 488 | if (BOOTSTRAPPER_ACTION_LAYOUT == action) |
486 | { | 489 | { |
487 | Assert(!pEngineState->plan.fPerMachine); | 490 | Assert(!pEngineState->plan.fPerMachine); |
@@ -521,6 +524,9 @@ extern "C" HRESULT CorePlan( | |||
521 | { | 524 | { |
522 | pEngineState->plan.fPerMachine = pEngineState->registration.fPerMachine; // default the scope of the plan to the per-machine state of the bundle. | 525 | pEngineState->plan.fPerMachine = pEngineState->registration.fPerMachine; // default the scope of the plan to the per-machine state of the bundle. |
523 | 526 | ||
527 | hr = PlanRelatedBundlesInitialize(&pEngineState->userExperience, &pEngineState->registration, pEngineState->command.relationType, &pEngineState->plan); | ||
528 | ExitOnFailure(hr, "Failed to initialize related bundles for plan."); | ||
529 | |||
524 | hr = PlanRegistration(&pEngineState->plan, &pEngineState->registration, &pEngineState->dependencies, pEngineState->command.resumeType, pEngineState->command.relationType, &fContinuePlanning); | 530 | hr = PlanRegistration(&pEngineState->plan, &pEngineState->registration, &pEngineState->dependencies, pEngineState->command.resumeType, pEngineState->command.relationType, &fContinuePlanning); |
525 | ExitOnFailure(hr, "Failed to plan registration."); | 531 | ExitOnFailure(hr, "Failed to plan registration."); |
526 | 532 | ||
@@ -918,8 +924,8 @@ extern "C" LPCWSTR CoreRelationTypeToCommandLineString( | |||
918 | case BOOTSTRAPPER_RELATION_UPDATE: | 924 | case BOOTSTRAPPER_RELATION_UPDATE: |
919 | wzRelationTypeCommandLine = BURN_COMMANDLINE_SWITCH_RELATED_UPDATE; | 925 | wzRelationTypeCommandLine = BURN_COMMANDLINE_SWITCH_RELATED_UPDATE; |
920 | break; | 926 | break; |
921 | case BOOTSTRAPPER_RELATION_DEPENDENT: | 927 | case BOOTSTRAPPER_RELATION_DEPENDENT_ADDON: __fallthrough; |
922 | break; | 928 | case BOOTSTRAPPER_RELATION_DEPENDENT_PATCH: __fallthrough; |
923 | case BOOTSTRAPPER_RELATION_NONE: __fallthrough; | 929 | case BOOTSTRAPPER_RELATION_NONE: __fallthrough; |
924 | default: | 930 | default: |
925 | wzRelationTypeCommandLine = NULL; | 931 | wzRelationTypeCommandLine = NULL; |
@@ -2308,7 +2314,7 @@ static void LogRelatedBundles( | |||
2308 | 2314 | ||
2309 | if (pRelatedBundle->fPlannable) | 2315 | if (pRelatedBundle->fPlannable) |
2310 | { | 2316 | { |
2311 | LogId(REPORT_STANDARD, MSG_PLANNED_RELATED_BUNDLE, pPackage->sczId, LoggingRelationTypeToString(pRelatedBundle->relationType), LoggingRequestStateToString(pPackage->defaultRequested), LoggingRequestStateToString(pPackage->requested), LoggingActionStateToString(pPackage->execute), LoggingActionStateToString(pPackage->rollback), LoggingRequestStateToString(pRelatedBundle->defaultRequestedRestore), LoggingRequestStateToString(pRelatedBundle->requestedRestore), LoggingActionStateToString(pRelatedBundle->restore), LoggingDependencyActionToString(pPackage->dependencyExecute)); | 2317 | LogId(REPORT_STANDARD, MSG_PLANNED_RELATED_BUNDLE, pPackage->sczId, LoggingRelationTypeToString(pRelatedBundle->detectRelationType), LoggingPlanRelationTypeToString(pRelatedBundle->defaultPlanRelationType), LoggingPlanRelationTypeToString(pRelatedBundle->planRelationType), LoggingRequestStateToString(pPackage->defaultRequested), LoggingRequestStateToString(pPackage->requested), LoggingActionStateToString(pPackage->execute), LoggingActionStateToString(pPackage->rollback), LoggingRequestStateToString(pRelatedBundle->defaultRequestedRestore), LoggingRequestStateToString(pRelatedBundle->requestedRestore), LoggingActionStateToString(pRelatedBundle->restore), LoggingDependencyActionToString(pPackage->dependencyExecute)); |
2312 | } | 2318 | } |
2313 | } | 2319 | } |
2314 | } | 2320 | } |
diff --git a/src/burn/engine/detect.cpp b/src/burn/engine/detect.cpp index f7a030ff..7628b26a 100644 --- a/src/burn/engine/detect.cpp +++ b/src/burn/engine/detect.cpp | |||
@@ -129,7 +129,7 @@ extern "C" HRESULT DetectForwardCompatibleBundles( | |||
129 | { | 129 | { |
130 | BURN_RELATED_BUNDLE* pRelatedBundle = pRegistration->relatedBundles.rgRelatedBundles + iRelatedBundle; | 130 | BURN_RELATED_BUNDLE* pRelatedBundle = pRegistration->relatedBundles.rgRelatedBundles + iRelatedBundle; |
131 | 131 | ||
132 | if (BOOTSTRAPPER_RELATION_UPGRADE == pRelatedBundle->relationType && | 132 | if (BOOTSTRAPPER_RELATION_UPGRADE == pRelatedBundle->detectRelationType && |
133 | CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, pRegistration->sczDetectedProviderKeyBundleId, -1, pRelatedBundle->package.sczId, -1)) | 133 | CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, pRegistration->sczDetectedProviderKeyBundleId, -1, pRelatedBundle->package.sczId, -1)) |
134 | { | 134 | { |
135 | hr = VerCompareParsedVersions(pRegistration->pVersion, pRelatedBundle->pVersion, &nCompareResult); | 135 | hr = VerCompareParsedVersions(pRegistration->pVersion, pRelatedBundle->pVersion, &nCompareResult); |
@@ -143,10 +143,10 @@ extern "C" HRESULT DetectForwardCompatibleBundles( | |||
143 | pRegistration->fForwardCompatibleBundleExists = TRUE; | 143 | pRegistration->fForwardCompatibleBundleExists = TRUE; |
144 | } | 144 | } |
145 | 145 | ||
146 | hr = UserExperienceOnDetectForwardCompatibleBundle(pUX, pRelatedBundle->package.sczId, pRelatedBundle->relationType, pRelatedBundle->sczTag, pRelatedBundle->package.fPerMachine, pRelatedBundle->pVersion, !pRelatedBundle->package.fCached); | 146 | hr = UserExperienceOnDetectForwardCompatibleBundle(pUX, pRelatedBundle->package.sczId, pRelatedBundle->detectRelationType, pRelatedBundle->sczTag, pRelatedBundle->package.fPerMachine, pRelatedBundle->pVersion, !pRelatedBundle->package.fCached); |
147 | ExitOnRootFailure(hr, "BA aborted detect forward compatible bundle."); | 147 | ExitOnRootFailure(hr, "BA aborted detect forward compatible bundle."); |
148 | 148 | ||
149 | LogId(REPORT_STANDARD, MSG_DETECTED_FORWARD_COMPATIBLE_BUNDLE, pRelatedBundle->package.sczId, LoggingRelationTypeToString(pRelatedBundle->relationType), LoggingPerMachineToString(pRelatedBundle->package.fPerMachine), pRelatedBundle->pVersion->sczVersion, LoggingBoolToString(pRelatedBundle->package.fCached)); | 149 | LogId(REPORT_STANDARD, MSG_DETECTED_FORWARD_COMPATIBLE_BUNDLE, pRelatedBundle->package.sczId, LoggingRelationTypeToString(pRelatedBundle->detectRelationType), LoggingPerMachineToString(pRelatedBundle->package.fPerMachine), pRelatedBundle->pVersion->sczVersion, LoggingBoolToString(pRelatedBundle->package.fCached)); |
150 | } | 150 | } |
151 | } | 151 | } |
152 | } | 152 | } |
@@ -164,6 +164,7 @@ extern "C" HRESULT DetectReportRelatedBundles( | |||
164 | ) | 164 | ) |
165 | { | 165 | { |
166 | HRESULT hr = S_OK; | 166 | HRESULT hr = S_OK; |
167 | BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE planRelationType = BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_NONE; | ||
167 | BOOTSTRAPPER_REQUEST_STATE uninstallRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE; | 168 | BOOTSTRAPPER_REQUEST_STATE uninstallRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE; |
168 | *pfEligibleForCleanup = BOOTSTRAPPER_REGISTRATION_TYPE_NONE != pRegistration->detectedRegistrationType || pRegistration->fCached; | 169 | *pfEligibleForCleanup = BOOTSTRAPPER_REGISTRATION_TYPE_NONE != pRegistration->detectedRegistrationType || pRegistration->fCached; |
169 | 170 | ||
@@ -171,16 +172,21 @@ extern "C" HRESULT DetectReportRelatedBundles( | |||
171 | { | 172 | { |
172 | const BURN_RELATED_BUNDLE* pRelatedBundle = pRegistration->relatedBundles.rgRelatedBundles + iRelatedBundle; | 173 | const BURN_RELATED_BUNDLE* pRelatedBundle = pRegistration->relatedBundles.rgRelatedBundles + iRelatedBundle; |
173 | 174 | ||
174 | LogId(REPORT_STANDARD, MSG_DETECTED_RELATED_BUNDLE, pRelatedBundle->package.sczId, LoggingRelationTypeToString(pRelatedBundle->relationType), LoggingPerMachineToString(pRelatedBundle->package.fPerMachine), pRelatedBundle->pVersion->sczVersion, LoggingBoolToString(pRelatedBundle->package.fCached)); | 175 | LogId(REPORT_STANDARD, MSG_DETECTED_RELATED_BUNDLE, pRelatedBundle->package.sczId, LoggingRelationTypeToString(pRelatedBundle->detectRelationType), LoggingPerMachineToString(pRelatedBundle->package.fPerMachine), pRelatedBundle->pVersion->sczVersion, LoggingBoolToString(pRelatedBundle->package.fCached)); |
175 | 176 | ||
176 | hr = UserExperienceOnDetectRelatedBundle(pUX, pRelatedBundle->package.sczId, pRelatedBundle->relationType, pRelatedBundle->sczTag, pRelatedBundle->package.fPerMachine, pRelatedBundle->pVersion, !pRelatedBundle->package.fCached); | 177 | hr = UserExperienceOnDetectRelatedBundle(pUX, pRelatedBundle->package.sczId, pRelatedBundle->detectRelationType, pRelatedBundle->sczTag, pRelatedBundle->package.fPerMachine, pRelatedBundle->pVersion, !pRelatedBundle->package.fCached); |
177 | ExitOnRootFailure(hr, "BA aborted detect related bundle."); | 178 | ExitOnRootFailure(hr, "BA aborted detect related bundle."); |
178 | 179 | ||
179 | // For now, if any related bundles will be executed during uninstall by default then never automatically clean up the bundle. | 180 | // For now, if any related bundles will be executed during uninstall by default then never automatically clean up the bundle. |
180 | if (*pfEligibleForCleanup && pRelatedBundle->fPlannable) | 181 | if (*pfEligibleForCleanup && pRelatedBundle->fPlannable) |
181 | { | 182 | { |
183 | planRelationType = BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_NONE; | ||
182 | uninstallRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE; | 184 | uninstallRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE; |
183 | hr = PlanDefaultRelatedBundleRequestState(relationType, pRelatedBundle->relationType, BOOTSTRAPPER_ACTION_UNINSTALL, pRegistration->pVersion, pRelatedBundle->pVersion, &uninstallRequestState); | 185 | |
186 | hr = PlanDefaultRelatedBundlePlanType(pRelatedBundle->detectRelationType, pRegistration->pVersion, pRelatedBundle->pVersion, &planRelationType); | ||
187 | ExitOnFailure(hr, "Failed to get the default plan type for related bundle for calculating fEligibleForCleanup"); | ||
188 | |||
189 | hr = PlanDefaultRelatedBundleRequestState(relationType, planRelationType, BOOTSTRAPPER_ACTION_UNINSTALL, &uninstallRequestState); | ||
184 | ExitOnFailure(hr, "Failed to get the default request state for related bundle for calculating fEligibleForCleanup"); | 190 | ExitOnFailure(hr, "Failed to get the default request state for related bundle for calculating fEligibleForCleanup"); |
185 | 191 | ||
186 | if (BOOTSTRAPPER_REQUEST_STATE_NONE != uninstallRequestState) | 192 | if (BOOTSTRAPPER_REQUEST_STATE_NONE != uninstallRequestState) |
diff --git a/src/burn/engine/elevation.cpp b/src/burn/engine/elevation.cpp index e479b6c0..636d67ce 100644 --- a/src/burn/engine/elevation.cpp +++ b/src/burn/engine/elevation.cpp | |||
@@ -874,6 +874,9 @@ extern "C" HRESULT ElevationExecuteRelatedBundle( | |||
874 | hr = BuffWriteNumber(&pbData, &cbData, (DWORD)pExecuteAction->relatedBundle.action); | 874 | hr = BuffWriteNumber(&pbData, &cbData, (DWORD)pExecuteAction->relatedBundle.action); |
875 | ExitOnFailure(hr, "Failed to write action to message buffer."); | 875 | ExitOnFailure(hr, "Failed to write action to message buffer."); |
876 | 876 | ||
877 | hr = BuffWriteNumber(&pbData, &cbData, (DWORD)pExecuteAction->relatedBundle.pRelatedBundle->planRelationType); | ||
878 | ExitOnFailure(hr, "Failed to write planRelationType to message buffer."); | ||
879 | |||
877 | hr = BuffWriteNumber(&pbData, &cbData, fRollback); | 880 | hr = BuffWriteNumber(&pbData, &cbData, fRollback); |
878 | ExitOnFailure(hr, "Failed to write rollback."); | 881 | ExitOnFailure(hr, "Failed to write rollback."); |
879 | 882 | ||
@@ -2723,6 +2726,7 @@ static HRESULT OnExecuteRelatedBundle( | |||
2723 | HRESULT hr = S_OK; | 2726 | HRESULT hr = S_OK; |
2724 | SIZE_T iData = 0; | 2727 | SIZE_T iData = 0; |
2725 | LPWSTR sczPackage = NULL; | 2728 | LPWSTR sczPackage = NULL; |
2729 | DWORD dwPlanRelationType = 0; | ||
2726 | DWORD dwRollback = 0; | 2730 | DWORD dwRollback = 0; |
2727 | BURN_EXECUTE_ACTION executeAction = { }; | 2731 | BURN_EXECUTE_ACTION executeAction = { }; |
2728 | LPWSTR sczIgnoreDependencies = NULL; | 2732 | LPWSTR sczIgnoreDependencies = NULL; |
@@ -2739,6 +2743,9 @@ static HRESULT OnExecuteRelatedBundle( | |||
2739 | hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&executeAction.relatedBundle.action); | 2743 | hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&executeAction.relatedBundle.action); |
2740 | ExitOnFailure(hr, "Failed to read action."); | 2744 | ExitOnFailure(hr, "Failed to read action."); |
2741 | 2745 | ||
2746 | hr = BuffReadNumber(pbData, cbData, &iData, &dwPlanRelationType); | ||
2747 | ExitOnFailure(hr, "Failed to read planRelationType."); | ||
2748 | |||
2742 | hr = BuffReadNumber(pbData, cbData, &iData, &dwRollback); | 2749 | hr = BuffReadNumber(pbData, cbData, &iData, &dwRollback); |
2743 | ExitOnFailure(hr, "Failed to read rollback."); | 2750 | ExitOnFailure(hr, "Failed to read rollback."); |
2744 | 2751 | ||
@@ -2757,6 +2764,8 @@ static HRESULT OnExecuteRelatedBundle( | |||
2757 | hr = RelatedBundleFindById(pRelatedBundles, sczPackage, &executeAction.relatedBundle.pRelatedBundle); | 2764 | hr = RelatedBundleFindById(pRelatedBundles, sczPackage, &executeAction.relatedBundle.pRelatedBundle); |
2758 | ExitOnFailure(hr, "Failed to find related bundle: %ls", sczPackage); | 2765 | ExitOnFailure(hr, "Failed to find related bundle: %ls", sczPackage); |
2759 | 2766 | ||
2767 | executeAction.relatedBundle.pRelatedBundle->planRelationType = (BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE)dwPlanRelationType; | ||
2768 | |||
2760 | // Pass the list of dependencies to ignore, if any, to the related bundle. | 2769 | // Pass the list of dependencies to ignore, if any, to the related bundle. |
2761 | if (sczIgnoreDependencies && *sczIgnoreDependencies) | 2770 | if (sczIgnoreDependencies && *sczIgnoreDependencies) |
2762 | { | 2771 | { |
diff --git a/src/burn/engine/engine.mc b/src/burn/engine/engine.mc index 6a826365..a5c4e2ba 100644 --- a/src/burn/engine/engine.mc +++ b/src/burn/engine/engine.mc | |||
@@ -384,7 +384,7 @@ MessageId=207 | |||
384 | Severity=Success | 384 | Severity=Success |
385 | SymbolicName=MSG_PLANNED_RELATED_BUNDLE | 385 | SymbolicName=MSG_PLANNED_RELATED_BUNDLE |
386 | Language=English | 386 | Language=English |
387 | Planned related bundle: %1!ls!, type: %2!hs!, default requested: %3!hs!, ba requested: %4!hs!, execute: %5!hs!, rollback: %6!hs!, default requested restore: %7!hs!, ba requested restore: %8!hs!, restore: %9!hs!, dependency: %10!hs! | 387 | Planned related bundle: %1!ls!, detect type: %2!hs!, default plan type: %3!hs!, ba plan type: %4!hs!, default requested: %5!hs!, ba requested: %6!hs!, execute: %7!hs!, rollback: %8!hs!, default requested restore: %9!hs!, ba requested restore: %10!hs!, restore: %11!hs!, dependency: %12!hs! |
388 | . | 388 | . |
389 | 389 | ||
390 | MessageId=208 | 390 | MessageId=208 |
@@ -426,14 +426,14 @@ MessageId=213 | |||
426 | Severity=Success | 426 | Severity=Success |
427 | SymbolicName=MSG_PLAN_SKIPPED_RELATED_BUNDLE_DEPENDENT | 427 | SymbolicName=MSG_PLAN_SKIPPED_RELATED_BUNDLE_DEPENDENT |
428 | Language=English | 428 | Language=English |
429 | Plan skipped related bundle: %1!ls!, type: %2!hs!, because it was dependent and the current bundle is being executed as type: %3!hs!. | 429 | Plan skipped related bundle: %1!ls!, because it was dependent and the current bundle is being executed as type: %2!hs!. |
430 | . | 430 | . |
431 | 431 | ||
432 | MessageId=214 | 432 | MessageId=214 |
433 | Severity=Success | 433 | Severity=Success |
434 | SymbolicName=MSG_PLAN_SKIPPED_RELATED_BUNDLE_SCHEDULED | 434 | SymbolicName=MSG_PLAN_SKIPPED_RELATED_BUNDLE_SCHEDULED |
435 | Language=English | 435 | Language=English |
436 | Plan skipped related bundle: %1!ls!, type: %2!hs!, because it was previously scheduled. | 436 | Plan skipped related bundle: %1!ls!, because it was previously scheduled. |
437 | . | 437 | . |
438 | 438 | ||
439 | MessageId=215 | 439 | MessageId=215 |
@@ -447,14 +447,14 @@ MessageId=216 | |||
447 | Severity=Success | 447 | Severity=Success |
448 | SymbolicName=MSG_PLAN_SKIPPED_RELATED_BUNDLE_EMBEDDED_BUNDLE_NEWER | 448 | SymbolicName=MSG_PLAN_SKIPPED_RELATED_BUNDLE_EMBEDDED_BUNDLE_NEWER |
449 | Language=English | 449 | Language=English |
450 | Plan skipped related bundle: %1!ls!, type: %2!hs!, provider key: %3!ls!, because an embedded bundle with the same provider key is being installed. | 450 | Plan skipped related bundle: %1!ls!, provider key: %2!ls!, because an embedded bundle with the same provider key is being installed. |
451 | . | 451 | . |
452 | 452 | ||
453 | MessageId=217 | 453 | MessageId=217 |
454 | Severity=Success | 454 | Severity=Success |
455 | SymbolicName=MSG_PLAN_SKIPPED_DEPENDENT_BUNDLE_REPAIR | 455 | SymbolicName=MSG_PLAN_SKIPPED_DEPENDENT_BUNDLE_REPAIR |
456 | Language=English | 456 | Language=English |
457 | Plan skipped dependent bundle repair: %1!ls!, type: %2!hs!, because no packages are being executed during this uninstall operation. | 457 | Plan skipped dependent bundle repair: %1!ls!, because no packages are being executed during this uninstall operation. |
458 | . | 458 | . |
459 | 459 | ||
460 | MessageId=218 | 460 | MessageId=218 |
diff --git a/src/burn/engine/logging.cpp b/src/burn/engine/logging.cpp index 07fc9ef3..2aa1bada 100644 --- a/src/burn/engine/logging.cpp +++ b/src/burn/engine/logging.cpp | |||
@@ -715,6 +715,31 @@ extern "C" LPCSTR LoggingResumeModeToString( | |||
715 | } | 715 | } |
716 | } | 716 | } |
717 | 717 | ||
718 | extern "C" LPCSTR LoggingPlanRelationTypeToString( | ||
719 | __in BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE type | ||
720 | ) | ||
721 | { | ||
722 | switch (type) | ||
723 | { | ||
724 | case BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_NONE: | ||
725 | return "None"; | ||
726 | case BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_DOWNGRADE: | ||
727 | return "Downgrade"; | ||
728 | case BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_UPGRADE: | ||
729 | return "Upgrade"; | ||
730 | case BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_ADDON: | ||
731 | return "Addon"; | ||
732 | case BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_PATCH: | ||
733 | return "Patch"; | ||
734 | case BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_DEPENDENT_ADDON: | ||
735 | return "DependentAddon"; | ||
736 | case BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_DEPENDENT_PATCH: | ||
737 | return "DependentPatch"; | ||
738 | default: | ||
739 | return "Invalid"; | ||
740 | } | ||
741 | } | ||
742 | |||
718 | extern "C" LPCSTR LoggingRelationTypeToString( | 743 | extern "C" LPCSTR LoggingRelationTypeToString( |
719 | __in BOOTSTRAPPER_RELATION_TYPE type | 744 | __in BOOTSTRAPPER_RELATION_TYPE type |
720 | ) | 745 | ) |
@@ -731,8 +756,10 @@ extern "C" LPCSTR LoggingRelationTypeToString( | |||
731 | return "Addon"; | 756 | return "Addon"; |
732 | case BOOTSTRAPPER_RELATION_PATCH: | 757 | case BOOTSTRAPPER_RELATION_PATCH: |
733 | return "Patch"; | 758 | return "Patch"; |
734 | case BOOTSTRAPPER_RELATION_DEPENDENT: | 759 | case BOOTSTRAPPER_RELATION_DEPENDENT_ADDON: |
735 | return "Dependent"; | 760 | return "DependentAddon"; |
761 | case BOOTSTRAPPER_RELATION_DEPENDENT_PATCH: | ||
762 | return "DependentPatch"; | ||
736 | case BOOTSTRAPPER_RELATION_UPDATE: | 763 | case BOOTSTRAPPER_RELATION_UPDATE: |
737 | return "Update"; | 764 | return "Update"; |
738 | default: | 765 | default: |
diff --git a/src/burn/engine/logging.h b/src/burn/engine/logging.h index ef603931..15eb298a 100644 --- a/src/burn/engine/logging.h +++ b/src/burn/engine/logging.h | |||
@@ -154,6 +154,10 @@ LPCSTR LoggingResumeModeToString( | |||
154 | __in BURN_RESUME_MODE resumeMode | 154 | __in BURN_RESUME_MODE resumeMode |
155 | ); | 155 | ); |
156 | 156 | ||
157 | LPCSTR LoggingPlanRelationTypeToString( | ||
158 | __in BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE type | ||
159 | ); | ||
160 | |||
157 | LPCSTR LoggingRelationTypeToString( | 161 | LPCSTR LoggingRelationTypeToString( |
158 | __in BOOTSTRAPPER_RELATION_TYPE type | 162 | __in BOOTSTRAPPER_RELATION_TYPE type |
159 | ); | 163 | ); |
diff --git a/src/burn/engine/plan.cpp b/src/burn/engine/plan.cpp index c9337df5..d3cc60f1 100644 --- a/src/burn/engine/plan.cpp +++ b/src/burn/engine/plan.cpp | |||
@@ -511,7 +511,7 @@ extern "C" HRESULT PlanForwardCompatibleBundles( | |||
511 | 511 | ||
512 | fIgnoreBundle = fRecommendIgnore; | 512 | fIgnoreBundle = fRecommendIgnore; |
513 | 513 | ||
514 | hr = UserExperienceOnPlanForwardCompatibleBundle(pUX, pRelatedBundle->package.sczId, pRelatedBundle->relationType, pRelatedBundle->sczTag, pRelatedBundle->package.fPerMachine, pRelatedBundle->pVersion, &fIgnoreBundle); | 514 | hr = UserExperienceOnPlanForwardCompatibleBundle(pUX, pRelatedBundle->package.sczId, pRelatedBundle->detectRelationType, pRelatedBundle->sczTag, pRelatedBundle->package.fPerMachine, pRelatedBundle->pVersion, &fIgnoreBundle); |
515 | ExitOnRootFailure(hr, "BA aborted plan forward compatible bundle."); | 515 | ExitOnRootFailure(hr, "BA aborted plan forward compatible bundle."); |
516 | 516 | ||
517 | if (!fIgnoreBundle) | 517 | if (!fIgnoreBundle) |
@@ -621,7 +621,8 @@ extern "C" HRESULT PlanRegistration( | |||
621 | { | 621 | { |
622 | const BURN_RELATED_BUNDLE* pRelatedBundle = pRegistration->relatedBundles.rgRelatedBundles + i; | 622 | const BURN_RELATED_BUNDLE* pRelatedBundle = pRegistration->relatedBundles.rgRelatedBundles + i; |
623 | 623 | ||
624 | if (BOOTSTRAPPER_RELATION_DEPENDENT == pRelatedBundle->relationType) | 624 | if (BOOTSTRAPPER_RELATION_DEPENDENT_ADDON == pRelatedBundle->planRelationType || |
625 | BOOTSTRAPPER_RELATION_DEPENDENT_PATCH == pRelatedBundle->planRelationType) | ||
625 | { | 626 | { |
626 | for (DWORD j = 0; j < pRelatedBundle->package.cDependencyProviders; ++j) | 627 | for (DWORD j = 0; j < pRelatedBundle->package.cDependencyProviders; ++j) |
627 | { | 628 | { |
@@ -703,7 +704,8 @@ extern "C" HRESULT PlanRegistration( | |||
703 | { | 704 | { |
704 | const BURN_RELATED_BUNDLE* pRelatedBundle = pRegistration->relatedBundles.rgRelatedBundles + i; | 705 | const BURN_RELATED_BUNDLE* pRelatedBundle = pRegistration->relatedBundles.rgRelatedBundles + i; |
705 | 706 | ||
706 | if (BOOTSTRAPPER_RELATION_DEPENDENT == pRelatedBundle->relationType) | 707 | if (BOOTSTRAPPER_RELATION_DEPENDENT_ADDON == pRelatedBundle->planRelationType || |
708 | BOOTSTRAPPER_RELATION_DEPENDENT_PATCH == pRelatedBundle->planRelationType) | ||
707 | { | 709 | { |
708 | for (DWORD j = 0; j < pRelatedBundle->package.cDependencyProviders; ++j) | 710 | for (DWORD j = 0; j < pRelatedBundle->package.cDependencyProviders; ++j) |
709 | { | 711 | { |
@@ -1212,17 +1214,63 @@ LExit: | |||
1212 | return hr; | 1214 | return hr; |
1213 | } | 1215 | } |
1214 | 1216 | ||
1215 | extern "C" HRESULT PlanDefaultRelatedBundleRequestState( | 1217 | extern "C" HRESULT PlanDefaultRelatedBundlePlanType( |
1216 | __in BOOTSTRAPPER_RELATION_TYPE commandRelationType, | ||
1217 | __in BOOTSTRAPPER_RELATION_TYPE relatedBundleRelationType, | 1218 | __in BOOTSTRAPPER_RELATION_TYPE relatedBundleRelationType, |
1218 | __in BOOTSTRAPPER_ACTION action, | ||
1219 | __in VERUTIL_VERSION* pRegistrationVersion, | 1219 | __in VERUTIL_VERSION* pRegistrationVersion, |
1220 | __in VERUTIL_VERSION* pRelatedBundleVersion, | 1220 | __in VERUTIL_VERSION* pRelatedBundleVersion, |
1221 | __inout BOOTSTRAPPER_REQUEST_STATE* pRequestState | 1221 | __inout BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE* pPlanRelationType |
1222 | ) | 1222 | ) |
1223 | { | 1223 | { |
1224 | HRESULT hr = S_OK; | 1224 | HRESULT hr = S_OK; |
1225 | int nCompareResult = 0; | 1225 | int nCompareResult = 0; |
1226 | |||
1227 | switch (relatedBundleRelationType) | ||
1228 | { | ||
1229 | case BOOTSTRAPPER_RELATION_UPGRADE: | ||
1230 | hr = VerCompareParsedVersions(pRegistrationVersion, pRelatedBundleVersion, &nCompareResult); | ||
1231 | ExitOnFailure(hr, "Failed to compare bundle version '%ls' to related bundle version '%ls'", pRegistrationVersion->sczVersion, pRelatedBundleVersion->sczVersion); | ||
1232 | |||
1233 | if (nCompareResult < 0) | ||
1234 | { | ||
1235 | *pPlanRelationType = BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_DOWNGRADE; | ||
1236 | } | ||
1237 | else | ||
1238 | { | ||
1239 | *pPlanRelationType = BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_UPGRADE; | ||
1240 | } | ||
1241 | break; | ||
1242 | case BOOTSTRAPPER_RELATION_ADDON: | ||
1243 | *pPlanRelationType = BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_ADDON; | ||
1244 | break; | ||
1245 | case BOOTSTRAPPER_RELATION_PATCH: | ||
1246 | *pPlanRelationType = BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_PATCH; | ||
1247 | break; | ||
1248 | case BOOTSTRAPPER_RELATION_DEPENDENT_ADDON: | ||
1249 | *pPlanRelationType = BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_DEPENDENT_ADDON; | ||
1250 | break; | ||
1251 | case BOOTSTRAPPER_RELATION_DEPENDENT_PATCH: | ||
1252 | *pPlanRelationType = BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_DEPENDENT_PATCH; | ||
1253 | break; | ||
1254 | case BOOTSTRAPPER_RELATION_DETECT: | ||
1255 | break; | ||
1256 | default: | ||
1257 | hr = E_UNEXPECTED; | ||
1258 | ExitOnFailure(hr, "Unexpected relation type encountered during plan: %d", relatedBundleRelationType); | ||
1259 | break; | ||
1260 | } | ||
1261 | |||
1262 | LExit: | ||
1263 | return hr; | ||
1264 | } | ||
1265 | |||
1266 | extern "C" HRESULT PlanDefaultRelatedBundleRequestState( | ||
1267 | __in BOOTSTRAPPER_RELATION_TYPE commandRelationType, | ||
1268 | __in BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE relatedBundleRelationType, | ||
1269 | __in BOOTSTRAPPER_ACTION action, | ||
1270 | __inout BOOTSTRAPPER_REQUEST_STATE* pRequestState | ||
1271 | ) | ||
1272 | { | ||
1273 | HRESULT hr = S_OK; | ||
1226 | BOOL fUninstalling = BOOTSTRAPPER_ACTION_UNINSTALL == action || BOOTSTRAPPER_ACTION_UNSAFE_UNINSTALL == action; | 1274 | BOOL fUninstalling = BOOTSTRAPPER_ACTION_UNINSTALL == action || BOOTSTRAPPER_ACTION_UNSAFE_UNINSTALL == action; |
1227 | 1275 | ||
1228 | // Never touch related bundles during Cache. | 1276 | // Never touch related bundles during Cache. |
@@ -1233,17 +1281,14 @@ extern "C" HRESULT PlanDefaultRelatedBundleRequestState( | |||
1233 | 1281 | ||
1234 | switch (relatedBundleRelationType) | 1282 | switch (relatedBundleRelationType) |
1235 | { | 1283 | { |
1236 | case BOOTSTRAPPER_RELATION_UPGRADE: | 1284 | case BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_UPGRADE: |
1237 | if (BOOTSTRAPPER_RELATION_UPGRADE != commandRelationType && !fUninstalling) | 1285 | if (BOOTSTRAPPER_RELATION_UPGRADE != commandRelationType && !fUninstalling) |
1238 | { | 1286 | { |
1239 | hr = VerCompareParsedVersions(pRegistrationVersion, pRelatedBundleVersion, &nCompareResult); | 1287 | *pRequestState = BOOTSTRAPPER_REQUEST_STATE_ABSENT; |
1240 | ExitOnFailure(hr, "Failed to compare bundle version '%ls' to related bundle version '%ls'", pRegistrationVersion ? pRegistrationVersion->sczVersion : NULL, pRelatedBundleVersion ? pRelatedBundleVersion->sczVersion : NULL); | ||
1241 | |||
1242 | *pRequestState = (nCompareResult < 0) ? BOOTSTRAPPER_REQUEST_STATE_NONE : BOOTSTRAPPER_REQUEST_STATE_ABSENT; | ||
1243 | } | 1288 | } |
1244 | break; | 1289 | break; |
1245 | case BOOTSTRAPPER_RELATION_PATCH: __fallthrough; | 1290 | case BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_PATCH: __fallthrough; |
1246 | case BOOTSTRAPPER_RELATION_ADDON: | 1291 | case BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_ADDON: |
1247 | if (fUninstalling) | 1292 | if (fUninstalling) |
1248 | { | 1293 | { |
1249 | *pRequestState = BOOTSTRAPPER_REQUEST_STATE_ABSENT; | 1294 | *pRequestState = BOOTSTRAPPER_REQUEST_STATE_ABSENT; |
@@ -1257,7 +1302,8 @@ extern "C" HRESULT PlanDefaultRelatedBundleRequestState( | |||
1257 | *pRequestState = BOOTSTRAPPER_REQUEST_STATE_REPAIR; | 1302 | *pRequestState = BOOTSTRAPPER_REQUEST_STATE_REPAIR; |
1258 | } | 1303 | } |
1259 | break; | 1304 | break; |
1260 | case BOOTSTRAPPER_RELATION_DEPENDENT: | 1305 | case BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_DEPENDENT_ADDON: __fallthrough; |
1306 | case BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_DEPENDENT_PATCH: | ||
1261 | // Automatically repair dependent bundles to restore missing | 1307 | // Automatically repair dependent bundles to restore missing |
1262 | // packages after uninstall unless we're being upgraded with the | 1308 | // packages after uninstall unless we're being upgraded with the |
1263 | // assumption that upgrades are cumulative (as intended). | 1309 | // assumption that upgrades are cumulative (as intended). |
@@ -1266,11 +1312,12 @@ extern "C" HRESULT PlanDefaultRelatedBundleRequestState( | |||
1266 | *pRequestState = BOOTSTRAPPER_REQUEST_STATE_REPAIR; | 1312 | *pRequestState = BOOTSTRAPPER_REQUEST_STATE_REPAIR; |
1267 | } | 1313 | } |
1268 | break; | 1314 | break; |
1269 | case BOOTSTRAPPER_RELATION_DETECT: | 1315 | case BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_DOWNGRADE: __fallthrough; |
1316 | case BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_NONE: | ||
1270 | break; | 1317 | break; |
1271 | default: | 1318 | default: |
1272 | hr = E_UNEXPECTED; | 1319 | hr = E_UNEXPECTED; |
1273 | ExitOnFailure(hr, "Unexpected relation type encountered during plan: %d", relatedBundleRelationType); | 1320 | ExitOnFailure(hr, "Unexpected plan relation type encountered during plan: %d", relatedBundleRelationType); |
1274 | break; | 1321 | break; |
1275 | } | 1322 | } |
1276 | 1323 | ||
@@ -1278,6 +1325,45 @@ LExit: | |||
1278 | return hr; | 1325 | return hr; |
1279 | } | 1326 | } |
1280 | 1327 | ||
1328 | extern "C" HRESULT PlanRelatedBundlesInitialize( | ||
1329 | __in BURN_USER_EXPERIENCE* pUserExperience, | ||
1330 | __in BURN_REGISTRATION* pRegistration, | ||
1331 | __in BOOTSTRAPPER_RELATION_TYPE /*relationType*/, | ||
1332 | __in BURN_PLAN* /*pPlan*/ | ||
1333 | ) | ||
1334 | { | ||
1335 | HRESULT hr = S_OK; | ||
1336 | |||
1337 | for (DWORD i = 0; i < pRegistration->relatedBundles.cRelatedBundles; ++i) | ||
1338 | { | ||
1339 | BURN_RELATED_BUNDLE* pRelatedBundle = pRegistration->relatedBundles.rgRelatedBundles + i; | ||
1340 | |||
1341 | pRelatedBundle->defaultRequestedRestore = BOOTSTRAPPER_REQUEST_STATE_NONE; | ||
1342 | pRelatedBundle->requestedRestore = BOOTSTRAPPER_REQUEST_STATE_NONE; | ||
1343 | pRelatedBundle->restore = BOOTSTRAPPER_ACTION_STATE_NONE; | ||
1344 | pRelatedBundle->package.defaultRequested = BOOTSTRAPPER_REQUEST_STATE_NONE; | ||
1345 | pRelatedBundle->package.requested = BOOTSTRAPPER_REQUEST_STATE_NONE; | ||
1346 | pRelatedBundle->defaultPlanRelationType = BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_NONE; | ||
1347 | pRelatedBundle->planRelationType = BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_NONE; | ||
1348 | |||
1349 | // Determine the plan relation type even if later it is ignored due to the planned action, the command relation type, or the related bundle not being plannable. | ||
1350 | // This gives more information to the BA in case it wants to override default behavior. | ||
1351 | // Doing it during plan instead of Detect allows the BA to change its mind without having to go all the way through Detect again. | ||
1352 | hr = PlanDefaultRelatedBundlePlanType(pRelatedBundle->detectRelationType, pRegistration->pVersion, pRelatedBundle->pVersion, &pRelatedBundle->defaultPlanRelationType); | ||
1353 | ExitOnFailure(hr, "Failed to get default plan type for related bundle."); | ||
1354 | |||
1355 | pRelatedBundle->planRelationType = pRelatedBundle->defaultPlanRelationType; | ||
1356 | |||
1357 | hr = UserExperienceOnPlanRelatedBundleType(pUserExperience, pRelatedBundle->package.sczId, &pRelatedBundle->planRelationType); | ||
1358 | ExitOnRootFailure(hr, "BA aborted plan related bundle type."); | ||
1359 | } | ||
1360 | |||
1361 | RelatedBundlesSortPlan(&pRegistration->relatedBundles); | ||
1362 | |||
1363 | LExit: | ||
1364 | return hr; | ||
1365 | } | ||
1366 | |||
1281 | extern "C" HRESULT PlanRelatedBundlesBegin( | 1367 | extern "C" HRESULT PlanRelatedBundlesBegin( |
1282 | __in BURN_USER_EXPERIENCE* pUserExperience, | 1368 | __in BURN_USER_EXPERIENCE* pUserExperience, |
1283 | __in BURN_REGISTRATION* pRegistration, | 1369 | __in BURN_REGISTRATION* pRegistration, |
@@ -1302,18 +1388,15 @@ extern "C" HRESULT PlanRelatedBundlesBegin( | |||
1302 | 1388 | ||
1303 | for (DWORD i = 0; i < pRegistration->relatedBundles.cRelatedBundles; ++i) | 1389 | for (DWORD i = 0; i < pRegistration->relatedBundles.cRelatedBundles; ++i) |
1304 | { | 1390 | { |
1305 | BURN_RELATED_BUNDLE* pRelatedBundle = pRegistration->relatedBundles.rgRelatedBundles + i; | 1391 | BURN_RELATED_BUNDLE* pRelatedBundle = pRegistration->relatedBundles.rgpPlanSortedRelatedBundles[i]; |
1306 | 1392 | ||
1307 | if (!pRelatedBundle->fPlannable) | 1393 | if (!pRelatedBundle->fPlannable) |
1308 | { | 1394 | { |
1309 | continue; | 1395 | continue; |
1310 | } | 1396 | } |
1311 | 1397 | ||
1312 | pRelatedBundle->defaultRequestedRestore = BOOTSTRAPPER_REQUEST_STATE_NONE; | 1398 | BOOL fDependent = BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_DEPENDENT_ADDON == pRelatedBundle->planRelationType || |
1313 | pRelatedBundle->requestedRestore = BOOTSTRAPPER_REQUEST_STATE_NONE; | 1399 | BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_DEPENDENT_PATCH == pRelatedBundle->planRelationType; |
1314 | pRelatedBundle->restore = BOOTSTRAPPER_ACTION_STATE_NONE; | ||
1315 | pRelatedBundle->package.defaultRequested = BOOTSTRAPPER_REQUEST_STATE_NONE; | ||
1316 | pRelatedBundle->package.requested = BOOTSTRAPPER_REQUEST_STATE_NONE; | ||
1317 | 1400 | ||
1318 | // Do not execute the same bundle twice. | 1401 | // Do not execute the same bundle twice. |
1319 | if (sdAncestors) | 1402 | if (sdAncestors) |
@@ -1321,7 +1404,7 @@ extern "C" HRESULT PlanRelatedBundlesBegin( | |||
1321 | hr = DictKeyExists(sdAncestors, pRelatedBundle->package.sczId); | 1404 | hr = DictKeyExists(sdAncestors, pRelatedBundle->package.sczId); |
1322 | if (SUCCEEDED(hr)) | 1405 | if (SUCCEEDED(hr)) |
1323 | { | 1406 | { |
1324 | LogId(REPORT_STANDARD, MSG_PLAN_SKIPPED_RELATED_BUNDLE_SCHEDULED, pRelatedBundle->package.sczId, LoggingRelationTypeToString(pRelatedBundle->relationType)); | 1407 | LogId(REPORT_STANDARD, MSG_PLAN_SKIPPED_RELATED_BUNDLE_SCHEDULED, pRelatedBundle->package.sczId); |
1325 | continue; | 1408 | continue; |
1326 | } | 1409 | } |
1327 | else if (E_NOTFOUND != hr) | 1410 | else if (E_NOTFOUND != hr) |
@@ -1329,10 +1412,10 @@ extern "C" HRESULT PlanRelatedBundlesBegin( | |||
1329 | ExitOnFailure(hr, "Failed to lookup the bundle ID in the ancestors dictionary."); | 1412 | ExitOnFailure(hr, "Failed to lookup the bundle ID in the ancestors dictionary."); |
1330 | } | 1413 | } |
1331 | } | 1414 | } |
1332 | else if (BOOTSTRAPPER_RELATION_DEPENDENT == pRelatedBundle->relationType && BOOTSTRAPPER_RELATION_NONE != relationType) | 1415 | else if (fDependent && BOOTSTRAPPER_RELATION_NONE != relationType) |
1333 | { | 1416 | { |
1334 | // Avoid repair loops for older bundles that do not handle ancestors. | 1417 | // Avoid repair loops for older bundles that do not handle ancestors. |
1335 | LogId(REPORT_STANDARD, MSG_PLAN_SKIPPED_RELATED_BUNDLE_DEPENDENT, pRelatedBundle->package.sczId, LoggingRelationTypeToString(pRelatedBundle->relationType), LoggingRelationTypeToString(relationType)); | 1418 | LogId(REPORT_STANDARD, MSG_PLAN_SKIPPED_RELATED_BUNDLE_DEPENDENT, pRelatedBundle->package.sczId, LoggingRelationTypeToString(relationType)); |
1336 | continue; | 1419 | continue; |
1337 | } | 1420 | } |
1338 | 1421 | ||
@@ -1340,7 +1423,7 @@ extern "C" HRESULT PlanRelatedBundlesBegin( | |||
1340 | pRelatedBundle->package.Bundle.wzAncestors = pRegistration->sczBundlePackageAncestors; | 1423 | pRelatedBundle->package.Bundle.wzAncestors = pRegistration->sczBundlePackageAncestors; |
1341 | pRelatedBundle->package.Bundle.wzEngineWorkingDirectory = pPlan->pInternalCommand->sczEngineWorkingDirectory; | 1424 | pRelatedBundle->package.Bundle.wzEngineWorkingDirectory = pPlan->pInternalCommand->sczEngineWorkingDirectory; |
1342 | 1425 | ||
1343 | hr = PlanDefaultRelatedBundleRequestState(relationType, pRelatedBundle->relationType, pPlan->action, pRegistration->pVersion, pRelatedBundle->pVersion, &pRelatedBundle->package.requested); | 1426 | hr = PlanDefaultRelatedBundleRequestState(relationType, pRelatedBundle->planRelationType, pPlan->action, &pRelatedBundle->package.requested); |
1344 | ExitOnFailure(hr, "Failed to get default request state for related bundle."); | 1427 | ExitOnFailure(hr, "Failed to get default request state for related bundle."); |
1345 | 1428 | ||
1346 | pRelatedBundle->package.defaultRequested = pRelatedBundle->package.requested; | 1429 | pRelatedBundle->package.defaultRequested = pRelatedBundle->package.requested; |
@@ -1349,7 +1432,7 @@ extern "C" HRESULT PlanRelatedBundlesBegin( | |||
1349 | ExitOnRootFailure(hr, "BA aborted plan related bundle."); | 1432 | ExitOnRootFailure(hr, "BA aborted plan related bundle."); |
1350 | 1433 | ||
1351 | // If uninstalling and the dependent related bundle may be executed, ignore its provider key to allow for downgrades with ref-counting. | 1434 | // If uninstalling and the dependent related bundle may be executed, ignore its provider key to allow for downgrades with ref-counting. |
1352 | if (fUninstalling && BOOTSTRAPPER_RELATION_DEPENDENT == pRelatedBundle->relationType && BOOTSTRAPPER_REQUEST_STATE_NONE != pRelatedBundle->package.requested) | 1435 | if (fUninstalling && fDependent && BOOTSTRAPPER_REQUEST_STATE_NONE != pRelatedBundle->package.requested) |
1353 | { | 1436 | { |
1354 | if (0 < pRelatedBundle->package.cDependencyProviders) | 1437 | if (0 < pRelatedBundle->package.cDependencyProviders) |
1355 | { | 1438 | { |
@@ -1437,7 +1520,11 @@ extern "C" HRESULT PlanRelatedBundlesComplete( | |||
1437 | for (DWORD i = 0; i < pRegistration->relatedBundles.cRelatedBundles; ++i) | 1520 | for (DWORD i = 0; i < pRegistration->relatedBundles.cRelatedBundles; ++i) |
1438 | { | 1521 | { |
1439 | DWORD *pdwInsertIndex = NULL; | 1522 | DWORD *pdwInsertIndex = NULL; |
1440 | BURN_RELATED_BUNDLE* pRelatedBundle = pRegistration->relatedBundles.rgRelatedBundles + i; | 1523 | BURN_RELATED_BUNDLE* pRelatedBundle = pRegistration->relatedBundles.rgpPlanSortedRelatedBundles[i]; |
1524 | BOOL fDependent = BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_DEPENDENT_ADDON == pRelatedBundle->planRelationType || | ||
1525 | BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_DEPENDENT_PATCH == pRelatedBundle->planRelationType; | ||
1526 | BOOL fAddonOrPatch = BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_ADDON == pRelatedBundle->planRelationType || | ||
1527 | BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_PATCH == pRelatedBundle->planRelationType; | ||
1441 | 1528 | ||
1442 | if (!pRelatedBundle->fPlannable) | 1529 | if (!pRelatedBundle->fPlannable) |
1443 | { | 1530 | { |
@@ -1454,7 +1541,7 @@ extern "C" HRESULT PlanRelatedBundlesComplete( | |||
1454 | { | 1541 | { |
1455 | ExitOnFailure(hr, "Failed to check the dictionary for a related bundle provider key: \"%ls\".", pProvider->sczKey); | 1542 | ExitOnFailure(hr, "Failed to check the dictionary for a related bundle provider key: \"%ls\".", pProvider->sczKey); |
1456 | // Key found, so there is an embedded bundle with the same provider key that will be executed. So this related bundle should not be added to the plan | 1543 | // Key found, so there is an embedded bundle with the same provider key that will be executed. So this related bundle should not be added to the plan |
1457 | LogId(REPORT_STANDARD, MSG_PLAN_SKIPPED_RELATED_BUNDLE_EMBEDDED_BUNDLE_NEWER, pRelatedBundle->package.sczId, LoggingRelationTypeToString(pRelatedBundle->relationType), pProvider->sczKey); | 1544 | LogId(REPORT_STANDARD, MSG_PLAN_SKIPPED_RELATED_BUNDLE_EMBEDDED_BUNDLE_NEWER, pRelatedBundle->package.sczId, pProvider->sczKey); |
1458 | continue; | 1545 | continue; |
1459 | } | 1546 | } |
1460 | else | 1547 | else |
@@ -1464,13 +1551,13 @@ extern "C" HRESULT PlanRelatedBundlesComplete( | |||
1464 | } | 1551 | } |
1465 | 1552 | ||
1466 | // For an uninstall, there is no need to repair dependent bundles if no packages are executing. | 1553 | // For an uninstall, there is no need to repair dependent bundles if no packages are executing. |
1467 | if (!fExecutingAnyPackage && BOOTSTRAPPER_RELATION_DEPENDENT == pRelatedBundle->relationType && BOOTSTRAPPER_REQUEST_STATE_REPAIR == pRelatedBundle->package.requested && fUninstalling) | 1554 | if (!fExecutingAnyPackage && fDependent && BOOTSTRAPPER_REQUEST_STATE_REPAIR == pRelatedBundle->package.requested && fUninstalling) |
1468 | { | 1555 | { |
1469 | pRelatedBundle->package.requested = BOOTSTRAPPER_REQUEST_STATE_NONE; | 1556 | pRelatedBundle->package.requested = BOOTSTRAPPER_REQUEST_STATE_NONE; |
1470 | LogId(REPORT_STANDARD, MSG_PLAN_SKIPPED_DEPENDENT_BUNDLE_REPAIR, pRelatedBundle->package.sczId, LoggingRelationTypeToString(pRelatedBundle->relationType)); | 1557 | LogId(REPORT_STANDARD, MSG_PLAN_SKIPPED_DEPENDENT_BUNDLE_REPAIR, pRelatedBundle->package.sczId); |
1471 | } | 1558 | } |
1472 | 1559 | ||
1473 | if (BOOTSTRAPPER_RELATION_ADDON == pRelatedBundle->relationType || BOOTSTRAPPER_RELATION_PATCH == pRelatedBundle->relationType) | 1560 | if (fAddonOrPatch) |
1474 | { | 1561 | { |
1475 | // Addon and patch bundles will be passed a list of dependencies to ignore for planning. | 1562 | // Addon and patch bundles will be passed a list of dependencies to ignore for planning. |
1476 | hr = StrAllocString(&pRelatedBundle->package.Bundle.sczIgnoreDependencies, sczIgnoreDependencies, 0); | 1563 | hr = StrAllocString(&pRelatedBundle->package.Bundle.sczIgnoreDependencies, sczIgnoreDependencies, 0); |
@@ -1489,7 +1576,7 @@ extern "C" HRESULT PlanRelatedBundlesComplete( | |||
1489 | ExitOnFailure(hr, "Failed to calculate plan for related bundle: %ls", pRelatedBundle->package.sczId); | 1576 | ExitOnFailure(hr, "Failed to calculate plan for related bundle: %ls", pRelatedBundle->package.sczId); |
1490 | 1577 | ||
1491 | // Calculate package states based on reference count for addon and patch related bundles. | 1578 | // Calculate package states based on reference count for addon and patch related bundles. |
1492 | if (BOOTSTRAPPER_RELATION_ADDON == pRelatedBundle->relationType || BOOTSTRAPPER_RELATION_PATCH == pRelatedBundle->relationType) | 1579 | if (fAddonOrPatch) |
1493 | { | 1580 | { |
1494 | hr = DependencyPlanPackageBegin(pRegistration->fPerMachine, &pRelatedBundle->package, pPlan); | 1581 | hr = DependencyPlanPackageBegin(pRegistration->fPerMachine, &pRelatedBundle->package, pPlan); |
1495 | ExitOnFailure(hr, "Failed to begin plan dependency actions to package: %ls", pRelatedBundle->package.sczId); | 1582 | ExitOnFailure(hr, "Failed to begin plan dependency actions to package: %ls", pRelatedBundle->package.sczId); |
@@ -1505,7 +1592,7 @@ extern "C" HRESULT PlanRelatedBundlesComplete( | |||
1505 | ExitOnFailure(hr, "Failed to add to plan related bundle: %ls", pRelatedBundle->package.sczId); | 1592 | ExitOnFailure(hr, "Failed to add to plan related bundle: %ls", pRelatedBundle->package.sczId); |
1506 | 1593 | ||
1507 | // Calculate package states based on reference count for addon and patch related bundles. | 1594 | // Calculate package states based on reference count for addon and patch related bundles. |
1508 | if (BOOTSTRAPPER_RELATION_ADDON == pRelatedBundle->relationType || BOOTSTRAPPER_RELATION_PATCH == pRelatedBundle->relationType) | 1595 | if (fAddonOrPatch) |
1509 | { | 1596 | { |
1510 | hr = DependencyPlanPackageComplete(&pRelatedBundle->package, pPlan); | 1597 | hr = DependencyPlanPackageComplete(&pRelatedBundle->package, pPlan); |
1511 | ExitOnFailure(hr, "Failed to complete plan dependency actions for related bundle package: %ls", pRelatedBundle->package.sczId); | 1598 | ExitOnFailure(hr, "Failed to complete plan dependency actions for related bundle package: %ls", pRelatedBundle->package.sczId); |
@@ -1517,7 +1604,7 @@ extern "C" HRESULT PlanRelatedBundlesComplete( | |||
1517 | PlannedExecutePackage(pPlan, &pRelatedBundle->package); | 1604 | PlannedExecutePackage(pPlan, &pRelatedBundle->package); |
1518 | } | 1605 | } |
1519 | } | 1606 | } |
1520 | else if (BOOTSTRAPPER_RELATION_ADDON == pRelatedBundle->relationType || BOOTSTRAPPER_RELATION_PATCH == pRelatedBundle->relationType) | 1607 | else if (fAddonOrPatch) |
1521 | { | 1608 | { |
1522 | // Make sure the package is properly ref-counted even if no plan is requested. | 1609 | // Make sure the package is properly ref-counted even if no plan is requested. |
1523 | hr = DependencyPlanPackageBegin(pRegistration->fPerMachine, &pRelatedBundle->package, pPlan); | 1610 | hr = DependencyPlanPackageBegin(pRegistration->fPerMachine, &pRelatedBundle->package, pPlan); |
@@ -1530,7 +1617,7 @@ extern "C" HRESULT PlanRelatedBundlesComplete( | |||
1530 | ExitOnFailure(hr, "Failed to complete plan dependency actions for related bundle package: %ls", pRelatedBundle->package.sczId); | 1617 | ExitOnFailure(hr, "Failed to complete plan dependency actions for related bundle package: %ls", pRelatedBundle->package.sczId); |
1531 | } | 1618 | } |
1532 | 1619 | ||
1533 | if (fInstallingAnyPackage && BOOTSTRAPPER_RELATION_UPGRADE == pRelatedBundle->relationType) | 1620 | if (fInstallingAnyPackage && BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_UPGRADE == pRelatedBundle->planRelationType) |
1534 | { | 1621 | { |
1535 | BURN_EXECUTE_ACTION* pAction = NULL; | 1622 | BURN_EXECUTE_ACTION* pAction = NULL; |
1536 | 1623 | ||
diff --git a/src/burn/engine/plan.h b/src/burn/engine/plan.h index 63bcd3ce..1f3fe07c 100644 --- a/src/burn/engine/plan.h +++ b/src/burn/engine/plan.h | |||
@@ -316,6 +316,12 @@ HRESULT PlanSetVariables( | |||
316 | __in BOOTSTRAPPER_ACTION action, | 316 | __in BOOTSTRAPPER_ACTION action, |
317 | __in BURN_VARIABLES* pVariables | 317 | __in BURN_VARIABLES* pVariables |
318 | ); | 318 | ); |
319 | HRESULT PlanDefaultRelatedBundlePlanType( | ||
320 | __in BOOTSTRAPPER_RELATION_TYPE relatedBundleRelationType, | ||
321 | __in VERUTIL_VERSION* pRegistrationVersion, | ||
322 | __in VERUTIL_VERSION* pRelatedBundleVersion, | ||
323 | __inout BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE* pPlanRelationType | ||
324 | ); | ||
319 | HRESULT PlanDefaultPackageRequestState( | 325 | HRESULT PlanDefaultPackageRequestState( |
320 | __in BURN_PACKAGE_TYPE packageType, | 326 | __in BURN_PACKAGE_TYPE packageType, |
321 | __in BOOTSTRAPPER_PACKAGE_STATE currentState, | 327 | __in BOOTSTRAPPER_PACKAGE_STATE currentState, |
@@ -383,12 +389,16 @@ HRESULT PlanExecutePackage( | |||
383 | ); | 389 | ); |
384 | HRESULT PlanDefaultRelatedBundleRequestState( | 390 | HRESULT PlanDefaultRelatedBundleRequestState( |
385 | __in BOOTSTRAPPER_RELATION_TYPE commandRelationType, | 391 | __in BOOTSTRAPPER_RELATION_TYPE commandRelationType, |
386 | __in BOOTSTRAPPER_RELATION_TYPE relatedBundleRelationType, | 392 | __in BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE relatedBundleRelationType, |
387 | __in BOOTSTRAPPER_ACTION action, | 393 | __in BOOTSTRAPPER_ACTION action, |
388 | __in VERUTIL_VERSION* pRegistrationVersion, | ||
389 | __in VERUTIL_VERSION* pRelatedBundleVersion, | ||
390 | __inout BOOTSTRAPPER_REQUEST_STATE* pRequestState | 394 | __inout BOOTSTRAPPER_REQUEST_STATE* pRequestState |
391 | ); | 395 | ); |
396 | HRESULT PlanRelatedBundlesInitialize( | ||
397 | __in BURN_USER_EXPERIENCE* pUserExperience, | ||
398 | __in BURN_REGISTRATION* pRegistration, | ||
399 | __in BOOTSTRAPPER_RELATION_TYPE relationType, | ||
400 | __in BURN_PLAN* pPlan | ||
401 | ); | ||
392 | HRESULT PlanRelatedBundlesBegin( | 402 | HRESULT PlanRelatedBundlesBegin( |
393 | __in BURN_USER_EXPERIENCE* pUserExperience, | 403 | __in BURN_USER_EXPERIENCE* pUserExperience, |
394 | __in BURN_REGISTRATION* pRegistration, | 404 | __in BURN_REGISTRATION* pRegistration, |
diff --git a/src/burn/engine/registration.cpp b/src/burn/engine/registration.cpp index 545c390b..6bae2e7b 100644 --- a/src/burn/engine/registration.cpp +++ b/src/burn/engine/registration.cpp | |||
@@ -614,7 +614,28 @@ extern "C" HRESULT RegistrationDetectRelatedBundles( | |||
614 | hr = RelatedBundlesInitializeForScope(FALSE, pRegistration, &pRegistration->relatedBundles); | 614 | hr = RelatedBundlesInitializeForScope(FALSE, pRegistration, &pRegistration->relatedBundles); |
615 | ExitOnFailure(hr, "Failed to initialize per-user related bundles."); | 615 | ExitOnFailure(hr, "Failed to initialize per-user related bundles."); |
616 | 616 | ||
617 | RelatedBundlesSort(&pRegistration->relatedBundles); | 617 | RelatedBundlesSortDetect(&pRegistration->relatedBundles); |
618 | |||
619 | LExit: | ||
620 | return hr; | ||
621 | } | ||
622 | |||
623 | extern "C" HRESULT RegistrationPlanInitialize( | ||
624 | __in BURN_REGISTRATION* pRegistration | ||
625 | ) | ||
626 | { | ||
627 | HRESULT hr = S_OK; | ||
628 | |||
629 | if (pRegistration->relatedBundles.cRelatedBundles && !pRegistration->relatedBundles.rgpPlanSortedRelatedBundles) | ||
630 | { | ||
631 | hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(&pRegistration->relatedBundles.rgpPlanSortedRelatedBundles), pRegistration->relatedBundles.cRelatedBundles, sizeof(BURN_RELATED_BUNDLE*), 5); | ||
632 | ExitOnFailure(hr, "Failed to initialize plan related bundles array."); | ||
633 | |||
634 | for (DWORD i = 0; i < pRegistration->relatedBundles.cRelatedBundles; ++i) | ||
635 | { | ||
636 | pRegistration->relatedBundles.rgpPlanSortedRelatedBundles[i] = pRegistration->relatedBundles.rgRelatedBundles + i; | ||
637 | } | ||
638 | } | ||
618 | 639 | ||
619 | LExit: | 640 | LExit: |
620 | return hr; | 641 | return hr; |
diff --git a/src/burn/engine/registration.h b/src/burn/engine/registration.h index bfaab1f1..e4dd6f4a 100644 --- a/src/burn/engine/registration.h +++ b/src/burn/engine/registration.h | |||
@@ -53,7 +53,9 @@ typedef struct _BURN_UPDATE_REGISTRATION | |||
53 | 53 | ||
54 | typedef struct _BURN_RELATED_BUNDLE | 54 | typedef struct _BURN_RELATED_BUNDLE |
55 | { | 55 | { |
56 | BOOTSTRAPPER_RELATION_TYPE relationType; | 56 | BOOTSTRAPPER_RELATION_TYPE detectRelationType; |
57 | BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE defaultPlanRelationType; | ||
58 | BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE planRelationType; | ||
57 | BOOL fForwardCompatible; | 59 | BOOL fForwardCompatible; |
58 | 60 | ||
59 | VERUTIL_VERSION* pVersion; | 61 | VERUTIL_VERSION* pVersion; |
@@ -71,6 +73,7 @@ typedef struct _BURN_RELATED_BUNDLES | |||
71 | { | 73 | { |
72 | BURN_RELATED_BUNDLE* rgRelatedBundles; | 74 | BURN_RELATED_BUNDLE* rgRelatedBundles; |
73 | DWORD cRelatedBundles; | 75 | DWORD cRelatedBundles; |
76 | BURN_RELATED_BUNDLE** rgpPlanSortedRelatedBundles; | ||
74 | } BURN_RELATED_BUNDLES; | 77 | } BURN_RELATED_BUNDLES; |
75 | 78 | ||
76 | typedef struct _BURN_SOFTWARE_TAG | 79 | typedef struct _BURN_SOFTWARE_TAG |
@@ -185,6 +188,9 @@ HRESULT RegistrationDetectResumeType( | |||
185 | HRESULT RegistrationDetectRelatedBundles( | 188 | HRESULT RegistrationDetectRelatedBundles( |
186 | __in BURN_REGISTRATION* pRegistration | 189 | __in BURN_REGISTRATION* pRegistration |
187 | ); | 190 | ); |
191 | HRESULT RegistrationPlanInitialize( | ||
192 | __in BURN_REGISTRATION* pRegistration | ||
193 | ); | ||
188 | HRESULT RegistrationSessionBegin( | 194 | HRESULT RegistrationSessionBegin( |
189 | __in_z LPCWSTR wzEngineWorkingPath, | 195 | __in_z LPCWSTR wzEngineWorkingPath, |
190 | __in BURN_REGISTRATION* pRegistration, | 196 | __in BURN_REGISTRATION* pRegistration, |
diff --git a/src/burn/engine/relatedbundle.cpp b/src/burn/engine/relatedbundle.cpp index e6633131..58911711 100644 --- a/src/burn/engine/relatedbundle.cpp +++ b/src/burn/engine/relatedbundle.cpp | |||
@@ -10,11 +10,16 @@ typedef struct _BUNDLE_QUERY_CONTEXT | |||
10 | 10 | ||
11 | // internal function declarations | 11 | // internal function declarations |
12 | 12 | ||
13 | static __callback int __cdecl CompareRelatedBundles( | 13 | static __callback int __cdecl CompareRelatedBundlesDetect( |
14 | __in void* pvContext, | 14 | __in void* pvContext, |
15 | __in const void* pvLeft, | 15 | __in const void* pvLeft, |
16 | __in const void* pvRight | 16 | __in const void* pvRight |
17 | ); | 17 | ); |
18 | static __callback int __cdecl CompareRelatedBundlesPlan( | ||
19 | __in void* /*pvContext*/, | ||
20 | __in const void* pvLeft, | ||
21 | __in const void* pvRight | ||
22 | ); | ||
18 | static BUNDLE_QUERY_CALLBACK_RESULT CALLBACK QueryRelatedBundlesCallback( | 23 | static BUNDLE_QUERY_CALLBACK_RESULT CALLBACK QueryRelatedBundlesCallback( |
19 | __in const BUNDLE_QUERY_RELATED_BUNDLE_RESULT* pBundle, | 24 | __in const BUNDLE_QUERY_RELATED_BUNDLE_RESULT* pBundle, |
20 | __in_opt LPVOID pvContext | 25 | __in_opt LPVOID pvContext |
@@ -88,6 +93,8 @@ extern "C" void RelatedBundlesUninitialize( | |||
88 | MemFree(pRelatedBundles->rgRelatedBundles); | 93 | MemFree(pRelatedBundles->rgRelatedBundles); |
89 | } | 94 | } |
90 | 95 | ||
96 | ReleaseMem(pRelatedBundles->rgpPlanSortedRelatedBundles); | ||
97 | |||
91 | memset(pRelatedBundles, 0, sizeof(BURN_RELATED_BUNDLES)); | 98 | memset(pRelatedBundles, 0, sizeof(BURN_RELATED_BUNDLES)); |
92 | } | 99 | } |
93 | 100 | ||
@@ -122,17 +129,24 @@ LExit: | |||
122 | return hr; | 129 | return hr; |
123 | } | 130 | } |
124 | 131 | ||
125 | extern "C" void RelatedBundlesSort( | 132 | extern "C" void RelatedBundlesSortDetect( |
133 | __in BURN_RELATED_BUNDLES* pRelatedBundles | ||
134 | ) | ||
135 | { | ||
136 | qsort_s(pRelatedBundles->rgRelatedBundles, pRelatedBundles->cRelatedBundles, sizeof(BURN_RELATED_BUNDLE), CompareRelatedBundlesDetect, NULL); | ||
137 | } | ||
138 | |||
139 | extern "C" void RelatedBundlesSortPlan( | ||
126 | __in BURN_RELATED_BUNDLES* pRelatedBundles | 140 | __in BURN_RELATED_BUNDLES* pRelatedBundles |
127 | ) | 141 | ) |
128 | { | 142 | { |
129 | qsort_s(pRelatedBundles->rgRelatedBundles, pRelatedBundles->cRelatedBundles, sizeof(BURN_RELATED_BUNDLE), CompareRelatedBundles, NULL); | 143 | qsort_s(pRelatedBundles->rgpPlanSortedRelatedBundles, pRelatedBundles->cRelatedBundles, sizeof(BURN_RELATED_BUNDLE*), CompareRelatedBundlesPlan, NULL); |
130 | } | 144 | } |
131 | 145 | ||
132 | 146 | ||
133 | // internal helper functions | 147 | // internal helper functions |
134 | 148 | ||
135 | static __callback int __cdecl CompareRelatedBundles( | 149 | static __callback int __cdecl CompareRelatedBundlesDetect( |
136 | __in void* /*pvContext*/, | 150 | __in void* /*pvContext*/, |
137 | __in const void* pvLeft, | 151 | __in const void* pvLeft, |
138 | __in const void* pvRight | 152 | __in const void* pvRight |
@@ -143,18 +157,61 @@ static __callback int __cdecl CompareRelatedBundles( | |||
143 | const BURN_RELATED_BUNDLE* pBundleRight = static_cast<const BURN_RELATED_BUNDLE*>(pvRight); | 157 | const BURN_RELATED_BUNDLE* pBundleRight = static_cast<const BURN_RELATED_BUNDLE*>(pvRight); |
144 | 158 | ||
145 | // Sort by relation type, then version, then bundle id. | 159 | // Sort by relation type, then version, then bundle id. |
146 | if (pBundleLeft->relationType != pBundleRight->relationType) | 160 | if (pBundleLeft->detectRelationType != pBundleRight->detectRelationType) |
147 | { | 161 | { |
148 | // Upgrade bundles last, everything else according to the enum. | 162 | // Upgrade bundles last, everything else according to the enum. |
149 | if (BOOTSTRAPPER_RELATION_UPGRADE == pBundleLeft->relationType) | 163 | if (BOOTSTRAPPER_RELATION_UPGRADE == pBundleLeft->detectRelationType) |
150 | { | 164 | { |
151 | ret = 1; | 165 | ret = 1; |
152 | } | 166 | } |
153 | else if (BOOTSTRAPPER_RELATION_UPGRADE == pBundleRight->relationType) | 167 | else if (BOOTSTRAPPER_RELATION_UPGRADE == pBundleRight->detectRelationType) |
154 | { | 168 | { |
155 | ret = -1; | 169 | ret = -1; |
156 | } | 170 | } |
157 | else if (pBundleLeft->relationType < pBundleRight->relationType) | 171 | else if (pBundleLeft->detectRelationType < pBundleRight->detectRelationType) |
172 | { | ||
173 | ret = -1; | ||
174 | } | ||
175 | else | ||
176 | { | ||
177 | ret = 1; | ||
178 | } | ||
179 | } | ||
180 | else | ||
181 | { | ||
182 | VerCompareParsedVersions(pBundleLeft->pVersion, pBundleRight->pVersion, &ret); | ||
183 | if (0 == ret) | ||
184 | { | ||
185 | ret = ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, pBundleLeft->package.sczId, -1, pBundleRight->package.sczId, -1) - 2; | ||
186 | } | ||
187 | } | ||
188 | |||
189 | return ret; | ||
190 | } | ||
191 | |||
192 | static __callback int __cdecl CompareRelatedBundlesPlan( | ||
193 | __in void* /*pvContext*/, | ||
194 | __in const void* pvLeft, | ||
195 | __in const void* pvRight | ||
196 | ) | ||
197 | { | ||
198 | int ret = 0; | ||
199 | const BURN_RELATED_BUNDLE* pBundleLeft = *reinterpret_cast<BURN_RELATED_BUNDLE**>(const_cast<void*>(pvLeft)); | ||
200 | const BURN_RELATED_BUNDLE* pBundleRight = *reinterpret_cast<BURN_RELATED_BUNDLE**>(const_cast<void*>(pvRight)); | ||
201 | |||
202 | // Sort by relation type, then version, then bundle id. | ||
203 | if (pBundleLeft->planRelationType != pBundleRight->planRelationType) | ||
204 | { | ||
205 | // Upgrade bundles last, everything else according to the enum. | ||
206 | if (BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_UPGRADE == pBundleLeft->planRelationType) | ||
207 | { | ||
208 | ret = 1; | ||
209 | } | ||
210 | else if (BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_UPGRADE == pBundleRight->planRelationType) | ||
211 | { | ||
212 | ret = -1; | ||
213 | } | ||
214 | else if (pBundleLeft->planRelationType < pBundleRight->planRelationType) | ||
158 | { | 215 | { |
159 | ret = -1; | 216 | ret = -1; |
160 | } | 217 | } |
@@ -191,6 +248,30 @@ LExit: | |||
191 | return result; | 248 | return result; |
192 | } | 249 | } |
193 | 250 | ||
251 | static BOOTSTRAPPER_RELATION_TYPE ConvertRelationType( | ||
252 | __in BUNDLE_RELATION_TYPE relationType | ||
253 | ) | ||
254 | { | ||
255 | switch (relationType) | ||
256 | { | ||
257 | case BUNDLE_RELATION_DETECT: | ||
258 | return BOOTSTRAPPER_RELATION_DETECT; | ||
259 | case BUNDLE_RELATION_UPGRADE: | ||
260 | return BOOTSTRAPPER_RELATION_UPGRADE; | ||
261 | case BUNDLE_RELATION_ADDON: | ||
262 | return BOOTSTRAPPER_RELATION_ADDON; | ||
263 | case BUNDLE_RELATION_PATCH: | ||
264 | return BOOTSTRAPPER_RELATION_PATCH; | ||
265 | case BUNDLE_RELATION_DEPENDENT_ADDON: | ||
266 | return BOOTSTRAPPER_RELATION_DEPENDENT_ADDON; | ||
267 | case BUNDLE_RELATION_DEPENDENT_PATCH: | ||
268 | return BOOTSTRAPPER_RELATION_DEPENDENT_PATCH; | ||
269 | default: | ||
270 | AssertSz(BUNDLE_RELATION_NONE == relationType, "Unknown BUNDLE_RELATION_TYPE"); | ||
271 | return BOOTSTRAPPER_RELATION_NONE; | ||
272 | } | ||
273 | } | ||
274 | |||
194 | static HRESULT LoadIfRelatedBundle( | 275 | static HRESULT LoadIfRelatedBundle( |
195 | __in const BUNDLE_QUERY_RELATED_BUNDLE_RESULT* pBundle, | 276 | __in const BUNDLE_QUERY_RELATED_BUNDLE_RESULT* pBundle, |
196 | __in BURN_REGISTRATION* pRegistration, | 277 | __in BURN_REGISTRATION* pRegistration, |
@@ -199,7 +280,7 @@ static HRESULT LoadIfRelatedBundle( | |||
199 | { | 280 | { |
200 | HRESULT hr = S_OK; | 281 | HRESULT hr = S_OK; |
201 | BOOL fPerMachine = BUNDLE_INSTALL_CONTEXT_MACHINE == pBundle->installContext; | 282 | BOOL fPerMachine = BUNDLE_INSTALL_CONTEXT_MACHINE == pBundle->installContext; |
202 | BOOTSTRAPPER_RELATION_TYPE relationType = (BOOTSTRAPPER_RELATION_TYPE)pBundle->relationType; | 283 | BOOTSTRAPPER_RELATION_TYPE relationType = ConvertRelationType(pBundle->relationType); |
203 | BURN_RELATED_BUNDLE* pRelatedBundle = NULL; | 284 | BURN_RELATED_BUNDLE* pRelatedBundle = NULL; |
204 | 285 | ||
205 | // If we found our bundle id, it's not a related bundle. | 286 | // If we found our bundle id, it's not a related bundle. |
@@ -316,11 +397,11 @@ static HRESULT LoadRelatedBundleFromKey( | |||
316 | } | 397 | } |
317 | ExitOnFailure(hr, "Failed to read tag from registry for bundle: %ls", wzRelatedBundleId); | 398 | ExitOnFailure(hr, "Failed to read tag from registry for bundle: %ls", wzRelatedBundleId); |
318 | 399 | ||
319 | pRelatedBundle->relationType = relationType; | 400 | pRelatedBundle->detectRelationType = relationType; |
320 | 401 | ||
321 | hr = PseudoBundleInitializeRelated(&pRelatedBundle->package, fSupportsBurnProtocol, fPerMachine, wzRelatedBundleId, | 402 | hr = PseudoBundleInitializeRelated(&pRelatedBundle->package, fSupportsBurnProtocol, fPerMachine, wzRelatedBundleId, |
322 | #ifdef DEBUG | 403 | #ifdef DEBUG |
323 | pRelatedBundle->relationType, | 404 | pRelatedBundle->detectRelationType, |
324 | #endif | 405 | #endif |
325 | fCached, sczCachePath, qwFileSize, pBundleDependencyProvider); | 406 | fCached, sczCachePath, qwFileSize, pBundleDependencyProvider); |
326 | ExitOnFailure(hr, "Failed to initialize related bundle to represent bundle: %ls", wzRelatedBundleId); | 407 | ExitOnFailure(hr, "Failed to initialize related bundle to represent bundle: %ls", wzRelatedBundleId); |
diff --git a/src/burn/engine/relatedbundle.h b/src/burn/engine/relatedbundle.h index be039421..24469f3d 100644 --- a/src/burn/engine/relatedbundle.h +++ b/src/burn/engine/relatedbundle.h | |||
@@ -19,7 +19,10 @@ HRESULT RelatedBundleFindById( | |||
19 | __in_z LPCWSTR wzId, | 19 | __in_z LPCWSTR wzId, |
20 | __out BURN_RELATED_BUNDLE** ppRelatedBundle | 20 | __out BURN_RELATED_BUNDLE** ppRelatedBundle |
21 | ); | 21 | ); |
22 | void RelatedBundlesSort( | 22 | void RelatedBundlesSortDetect( |
23 | __in BURN_RELATED_BUNDLES* pRelatedBundles | ||
24 | ); | ||
25 | void RelatedBundlesSortPlan( | ||
23 | __in BURN_RELATED_BUNDLES* pRelatedBundles | 26 | __in BURN_RELATED_BUNDLES* pRelatedBundles |
24 | ); | 27 | ); |
25 | 28 | ||
diff --git a/src/burn/engine/userexperience.cpp b/src/burn/engine/userexperience.cpp index f299772b..8668cf6f 100644 --- a/src/burn/engine/userexperience.cpp +++ b/src/burn/engine/userexperience.cpp | |||
@@ -104,7 +104,7 @@ extern "C" HRESULT UserExperienceLoad( | |||
104 | args.pCommand = pCommand; | 104 | args.pCommand = pCommand; |
105 | args.pfnBootstrapperEngineProc = EngineForApplicationProc; | 105 | args.pfnBootstrapperEngineProc = EngineForApplicationProc; |
106 | args.pvBootstrapperEngineProcContext = pEngineContext; | 106 | args.pvBootstrapperEngineProcContext = pEngineContext; |
107 | args.qwEngineAPIVersion = MAKEQWORDVERSION(2022, 3, 4, 0); | 107 | args.qwEngineAPIVersion = MAKEQWORDVERSION(2022, 3, 14, 0); |
108 | 108 | ||
109 | results.cbSize = sizeof(BOOTSTRAPPER_CREATE_RESULTS); | 109 | results.cbSize = sizeof(BOOTSTRAPPER_CREATE_RESULTS); |
110 | 110 | ||
@@ -2176,6 +2176,36 @@ LExit: | |||
2176 | return hr; | 2176 | return hr; |
2177 | } | 2177 | } |
2178 | 2178 | ||
2179 | EXTERN_C BAAPI UserExperienceOnPlanRelatedBundleType( | ||
2180 | __in BURN_USER_EXPERIENCE* pUserExperience, | ||
2181 | __in_z LPCWSTR wzBundleId, | ||
2182 | __inout BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE* pRequestedType | ||
2183 | ) | ||
2184 | { | ||
2185 | HRESULT hr = S_OK; | ||
2186 | BA_ONPLANRELATEDBUNDLETYPE_ARGS args = { }; | ||
2187 | BA_ONPLANRELATEDBUNDLETYPE_RESULTS results = { }; | ||
2188 | |||
2189 | args.cbSize = sizeof(args); | ||
2190 | args.wzBundleId = wzBundleId; | ||
2191 | args.recommendedType = *pRequestedType; | ||
2192 | |||
2193 | results.cbSize = sizeof(results); | ||
2194 | results.requestedType = *pRequestedType; | ||
2195 | |||
2196 | hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANRELATEDBUNDLETYPE, &args, &results); | ||
2197 | ExitOnFailure(hr, "BA OnPlanRelatedBundleType failed."); | ||
2198 | |||
2199 | if (results.fCancel) | ||
2200 | { | ||
2201 | hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); | ||
2202 | } | ||
2203 | *pRequestedType = results.requestedType; | ||
2204 | |||
2205 | LExit: | ||
2206 | return hr; | ||
2207 | } | ||
2208 | |||
2179 | EXTERN_C BAAPI UserExperienceOnPlanRestoreRelatedBundle( | 2209 | EXTERN_C BAAPI UserExperienceOnPlanRestoreRelatedBundle( |
2180 | __in BURN_USER_EXPERIENCE* pUserExperience, | 2210 | __in BURN_USER_EXPERIENCE* pUserExperience, |
2181 | __in_z LPCWSTR wzBundleId, | 2211 | __in_z LPCWSTR wzBundleId, |
diff --git a/src/burn/engine/userexperience.h b/src/burn/engine/userexperience.h index 37fa5174..11344365 100644 --- a/src/burn/engine/userexperience.h +++ b/src/burn/engine/userexperience.h | |||
@@ -497,6 +497,11 @@ BAAPI UserExperienceOnPlanRelatedBundle( | |||
497 | __in_z LPCWSTR wzBundleId, | 497 | __in_z LPCWSTR wzBundleId, |
498 | __inout BOOTSTRAPPER_REQUEST_STATE* pRequestedState | 498 | __inout BOOTSTRAPPER_REQUEST_STATE* pRequestedState |
499 | ); | 499 | ); |
500 | BAAPI UserExperienceOnPlanRelatedBundleType( | ||
501 | __in BURN_USER_EXPERIENCE* pUserExperience, | ||
502 | __in_z LPCWSTR wzBundleId, | ||
503 | __inout BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE* pRequestedType | ||
504 | ); | ||
500 | BAAPI UserExperienceOnPlanRestoreRelatedBundle( | 505 | BAAPI UserExperienceOnPlanRestoreRelatedBundle( |
501 | __in BURN_USER_EXPERIENCE* pUserExperience, | 506 | __in BURN_USER_EXPERIENCE* pUserExperience, |
502 | __in_z LPCWSTR wzBundleId, | 507 | __in_z LPCWSTR wzBundleId, |