diff options
| author | Bob Arnson <bob@firegiant.com> | 2026-02-04 20:47:04 -0500 |
|---|---|---|
| committer | Bob Arnson <bob@firegiant.com> | 2026-02-04 20:47:04 -0500 |
| commit | edccb203c421d2bd820062024088c6698424d9ee (patch) | |
| tree | 6b47c3eb5ca53bd9f79f3d032dc1a596d411bf38 /src/burn/engine | |
| parent | a3d3963f806117ce123d95e8b77e73e1c1545b25 (diff) | |
| download | wix-edccb203c421d2bd820062024088c6698424d9ee.tar.gz wix-edccb203c421d2bd820062024088c6698424d9ee.tar.bz2 wix-edccb203c421d2bd820062024088c6698424d9ee.zip | |
Support dual-purpose packages in Burn.bob/ConfigurableScopeBundles
Fixes https://github.com/wixtoolset/issues/issues/8958
Diffstat (limited to 'src/burn/engine')
27 files changed, 597 insertions, 189 deletions
diff --git a/src/burn/engine/apply.cpp b/src/burn/engine/apply.cpp index e4e76a6c..68aded71 100644 --- a/src/burn/engine/apply.cpp +++ b/src/burn/engine/apply.cpp | |||
| @@ -632,7 +632,7 @@ extern "C" HRESULT ApplyCache( | |||
| 632 | { | 632 | { |
| 633 | hr = ElevationCachePreparePackage(hPipe, pPackage); | 633 | hr = ElevationCachePreparePackage(hPipe, pPackage); |
| 634 | } | 634 | } |
| 635 | LogExitOnFailure(hr, MSG_CACHE_PREPARE_PACKAGE_FAILED, "Cache prepare package failed: %ls", pPackage->sczId, NULL, NULL); | 635 | LogExitOnFailure(hr, MSG_CACHE_PREPARE_PACKAGE_FAILED, "Cache prepare package failed: %ls", pPackage->sczId); |
| 636 | } | 636 | } |
| 637 | 637 | ||
| 638 | hr = ApplyCachePackage(&cacheContext, pPackage); | 638 | hr = ApplyCachePackage(&cacheContext, pPackage); |
diff --git a/src/burn/engine/baengine.cpp b/src/burn/engine/baengine.cpp index d1704ad9..e48f71c0 100644 --- a/src/burn/engine/baengine.cpp +++ b/src/burn/engine/baengine.cpp | |||
| @@ -1134,12 +1134,15 @@ static HRESULT BAEnginePlan( | |||
| 1134 | hr = BuffReaderReadNumber(pReaderArgs, reinterpret_cast<DWORD*>(&args.action)); | 1134 | hr = BuffReaderReadNumber(pReaderArgs, reinterpret_cast<DWORD*>(&args.action)); |
| 1135 | ExitOnFailure(hr, "Failed to read plan action of BAEnginePlan args."); | 1135 | ExitOnFailure(hr, "Failed to read plan action of BAEnginePlan args."); |
| 1136 | 1136 | ||
| 1137 | hr = BuffReaderReadNumber(pReaderArgs, reinterpret_cast<DWORD*>(&args.plannedScope)); | ||
| 1138 | ExitOnFailure(hr, "Failed to read plan scope of BAEnginePlan args."); | ||
| 1139 | |||
| 1137 | // Read results. | 1140 | // Read results. |
| 1138 | hr = BuffReaderReadNumber(pReaderResults, &results.dwApiVersion); | 1141 | hr = BuffReaderReadNumber(pReaderResults, &results.dwApiVersion); |
| 1139 | ExitOnFailure(hr, "Failed to read API version of BAEnginePlan results."); | 1142 | ExitOnFailure(hr, "Failed to read API version of BAEnginePlan results."); |
| 1140 | 1143 | ||
| 1141 | // Execute. | 1144 | // Execute. |
| 1142 | hr = ExternalEnginePlan(pContext, args.action); | 1145 | hr = ExternalEnginePlan(pContext, args.action, args.plannedScope); |
| 1143 | ExitOnFailure(hr, "Failed to plan in the engine."); | 1146 | ExitOnFailure(hr, "Failed to plan in the engine."); |
| 1144 | 1147 | ||
| 1145 | // Pack result. | 1148 | // Pack result. |
diff --git a/src/burn/engine/baengine.h b/src/burn/engine/baengine.h index 97cfea9c..39e5ae0b 100644 --- a/src/burn/engine/baengine.h +++ b/src/burn/engine/baengine.h | |||
| @@ -31,6 +31,7 @@ typedef struct _BAENGINE_ACTION | |||
| 31 | struct | 31 | struct |
| 32 | { | 32 | { |
| 33 | BOOTSTRAPPER_ACTION action; | 33 | BOOTSTRAPPER_ACTION action; |
| 34 | BOOTSTRAPPER_SCOPE plannedScope; | ||
| 34 | } plan; | 35 | } plan; |
| 35 | struct | 36 | struct |
| 36 | { | 37 | { |
diff --git a/src/burn/engine/cache.cpp b/src/burn/engine/cache.cpp index c85a1be4..21bd42be 100644 --- a/src/burn/engine/cache.cpp +++ b/src/burn/engine/cache.cpp | |||
| @@ -36,8 +36,8 @@ static HRESULT SecurePerMachineCacheRoot( | |||
| 36 | static HRESULT CreateCompletedPath( | 36 | static HRESULT CreateCompletedPath( |
| 37 | __in BURN_CACHE* pCache, | 37 | __in BURN_CACHE* pCache, |
| 38 | __in BOOL fPerMachine, | 38 | __in BOOL fPerMachine, |
| 39 | __in LPCWSTR wzCacheId, | 39 | __in_z LPCWSTR wzId, |
| 40 | __in LPCWSTR wzFilePath, | 40 | __in_z_opt LPCWSTR wzFilePath, |
| 41 | __out_z LPWSTR* psczCachePath | 41 | __out_z LPWSTR* psczCachePath |
| 42 | ); | 42 | ); |
| 43 | static HRESULT CreateUnverifiedPath( | 43 | static HRESULT CreateUnverifiedPath( |
| @@ -1658,8 +1658,8 @@ LExit: | |||
| 1658 | static HRESULT CreateCompletedPath( | 1658 | static HRESULT CreateCompletedPath( |
| 1659 | __in BURN_CACHE* pCache, | 1659 | __in BURN_CACHE* pCache, |
| 1660 | __in BOOL fPerMachine, | 1660 | __in BOOL fPerMachine, |
| 1661 | __in LPCWSTR wzId, | 1661 | __in_z LPCWSTR wzId, |
| 1662 | __in LPCWSTR wzFilePath, | 1662 | __in_z_opt LPCWSTR wzFilePath, |
| 1663 | __out_z LPWSTR* psczCachePath | 1663 | __out_z LPWSTR* psczCachePath |
| 1664 | ) | 1664 | ) |
| 1665 | { | 1665 | { |
diff --git a/src/burn/engine/core.cpp b/src/burn/engine/core.cpp index 2dfa4857..7937bd65 100644 --- a/src/burn/engine/core.cpp +++ b/src/burn/engine/core.cpp | |||
| @@ -379,7 +379,7 @@ extern "C" HRESULT CoreDetect( | |||
| 379 | pEngineState->registration.fEligibleForCleanup = FALSE; | 379 | pEngineState->registration.fEligibleForCleanup = FALSE; |
| 380 | } | 380 | } |
| 381 | 381 | ||
| 382 | LogId(REPORT_STANDARD, MSG_DETECTED_PACKAGE, pPackage->sczId, LoggingPackageStateToString(pPackage->currentState), LoggingBoolToString(pPackage->fCached), LoggingPackageRegistrationStateToString(pPackage->fCanAffectRegistration, pPackage->installRegistrationState), LoggingPackageRegistrationStateToString(pPackage->fCanAffectRegistration, pPackage->cacheRegistrationState)); | 382 | LogId(REPORT_STANDARD, MSG_DETECTED_PACKAGE, pPackage->sczId, LoggingPackageStateToString(pPackage->currentState), LoggingBoolToString(pPackage->fCached), LoggingPackageRegistrationStateToString(pPackage->fCanAffectRegistration, pPackage->installRegistrationState), LoggingPackageRegistrationStateToString(pPackage->fCanAffectRegistration, pPackage->cacheRegistrationState), LoggingPackageScopeToString(pPackage->scope)); |
| 383 | 383 | ||
| 384 | if (BURN_PACKAGE_TYPE_MSI == pPackage->type) | 384 | if (BURN_PACKAGE_TYPE_MSI == pPackage->type) |
| 385 | { | 385 | { |
| @@ -424,8 +424,9 @@ LExit: | |||
| 424 | 424 | ||
| 425 | extern "C" HRESULT CorePlan( | 425 | extern "C" HRESULT CorePlan( |
| 426 | __in BURN_ENGINE_STATE* pEngineState, | 426 | __in BURN_ENGINE_STATE* pEngineState, |
| 427 | __in BOOTSTRAPPER_ACTION action | 427 | __in BOOTSTRAPPER_ACTION action, |
| 428 | ) | 428 | __in BOOTSTRAPPER_SCOPE plannedScope |
| 429 | ) | ||
| 429 | { | 430 | { |
| 430 | HRESULT hr = S_OK; | 431 | HRESULT hr = S_OK; |
| 431 | BOOL fPlanBegan = FALSE; | 432 | BOOL fPlanBegan = FALSE; |
| @@ -433,7 +434,7 @@ extern "C" HRESULT CorePlan( | |||
| 433 | BURN_PACKAGE* pForwardCompatibleBundlePackage = NULL; | 434 | BURN_PACKAGE* pForwardCompatibleBundlePackage = NULL; |
| 434 | BOOL fContinuePlanning = TRUE; // assume we won't skip planning due to dependencies. | 435 | BOOL fContinuePlanning = TRUE; // assume we won't skip planning due to dependencies. |
| 435 | 436 | ||
| 436 | LogId(REPORT_STANDARD, MSG_PLAN_BEGIN, pEngineState->packages.cPackages, LoggingBurnActionToString(action)); | 437 | LogId(REPORT_STANDARD, MSG_PLAN_BEGIN, pEngineState->packages.cPackages, LoggingBurnActionToString(action), LoggingBundleScopeToString(plannedScope)); |
| 437 | 438 | ||
| 438 | fPlanBegan = TRUE; | 439 | fPlanBegan = TRUE; |
| 439 | hr = BACallbackOnPlanBegin(&pEngineState->userExperience, pEngineState->packages.cPackages); | 440 | hr = BACallbackOnPlanBegin(&pEngineState->userExperience, pEngineState->packages.cPackages); |
| @@ -452,12 +453,13 @@ extern "C" HRESULT CorePlan( | |||
| 452 | pEngineState->fPlanned = FALSE; | 453 | pEngineState->fPlanned = FALSE; |
| 453 | PlanReset(&pEngineState->plan, &pEngineState->variables, &pEngineState->containers, &pEngineState->packages, &pEngineState->layoutPayloads); | 454 | PlanReset(&pEngineState->plan, &pEngineState->variables, &pEngineState->containers, &pEngineState->packages, &pEngineState->layoutPayloads); |
| 454 | 455 | ||
| 455 | hr = PlanSetVariables(action, &pEngineState->variables); | 456 | hr = PlanSetVariables(action, pEngineState->registration.scope, pEngineState->plan.plannedScope, &pEngineState->variables); |
| 456 | ExitOnFailure(hr, "Failed to update action."); | 457 | ExitOnFailure(hr, "Failed to update plan variables."); |
| 457 | 458 | ||
| 458 | // Remember the overall action state in the plan since it shapes the changes | 459 | // Remember the overall action state in the plan since it shapes the changes |
| 459 | // we make everywhere. | 460 | // we make everywhere. |
| 460 | pEngineState->plan.action = action; | 461 | pEngineState->plan.action = action; |
| 462 | pEngineState->plan.plannedScope = plannedScope; | ||
| 461 | pEngineState->plan.pCache = &pEngineState->cache; | 463 | pEngineState->plan.pCache = &pEngineState->cache; |
| 462 | pEngineState->plan.pCommand = &pEngineState->command; | 464 | pEngineState->plan.pCommand = &pEngineState->command; |
| 463 | pEngineState->plan.pInternalCommand = &pEngineState->internalCommand; | 465 | pEngineState->plan.pInternalCommand = &pEngineState->internalCommand; |
| @@ -467,6 +469,17 @@ extern "C" HRESULT CorePlan( | |||
| 467 | pEngineState->plan.fDisableRollback = pEngineState->fDisableRollback || BOOTSTRAPPER_ACTION_UNSAFE_UNINSTALL == pEngineState->plan.action; | 469 | pEngineState->plan.fDisableRollback = pEngineState->fDisableRollback || BOOTSTRAPPER_ACTION_UNSAFE_UNINSTALL == pEngineState->plan.action; |
| 468 | pEngineState->plan.fPlanPackageCacheRollback = BOOTSTRAPPER_REGISTRATION_TYPE_NONE == pEngineState->registration.detectedRegistrationType; | 470 | pEngineState->plan.fPlanPackageCacheRollback = BOOTSTRAPPER_REGISTRATION_TYPE_NONE == pEngineState->registration.detectedRegistrationType; |
| 469 | 471 | ||
| 472 | hr = PlanPackagesAndBundleScope(pEngineState->packages.rgPackages, pEngineState->packages.cPackages, pEngineState->plan.plannedScope, pEngineState->registration.scope, pEngineState->command.commandLineScope, &pEngineState->plan.plannedScope, &pEngineState->registration.fPerMachine); | ||
| 473 | ExitOnFailure(hr, "Failed to determine packages and bundle scope."); | ||
| 474 | |||
| 475 | if (BOOTSTRAPPER_PACKAGE_SCOPE_PER_MACHINE_OR_PER_USER == pEngineState->registration.scope || BOOTSTRAPPER_PACKAGE_SCOPE_PER_USER_OR_PER_MACHINE == pEngineState->registration.scope) | ||
| 476 | { | ||
| 477 | LogId(REPORT_STANDARD, MSG_PLAN_CONFIGURED_SCOPE, LoggingInstallScopeToString(pEngineState->registration.fPerMachine)); | ||
| 478 | } | ||
| 479 | |||
| 480 | hr = RegistrationSetPaths(&pEngineState->registration, &pEngineState->cache); | ||
| 481 | ExitOnFailure(hr, "Failed to set registration paths."); | ||
| 482 | |||
| 470 | // Set resume commandline | 483 | // Set resume commandline |
| 471 | hr = PlanSetResumeCommand(&pEngineState->plan, &pEngineState->registration, &pEngineState->log); | 484 | hr = PlanSetResumeCommand(&pEngineState->plan, &pEngineState->registration, &pEngineState->log); |
| 472 | ExitOnFailure(hr, "Failed to set resume command"); | 485 | ExitOnFailure(hr, "Failed to set resume command"); |
| @@ -475,7 +488,7 @@ extern "C" HRESULT CorePlan( | |||
| 475 | ExitOnFailure(hr, "Failed to initialize the dependencies for the plan."); | 488 | ExitOnFailure(hr, "Failed to initialize the dependencies for the plan."); |
| 476 | 489 | ||
| 477 | hr = RegistrationPlanInitialize(&pEngineState->registration); | 490 | hr = RegistrationPlanInitialize(&pEngineState->registration); |
| 478 | ExitOnFailure(hr, "Failed to initialize registration for the plan."); | 491 | ExitOnFailure(hr, "Failed to initialize the plan for registration."); |
| 479 | 492 | ||
| 480 | if (BOOTSTRAPPER_ACTION_LAYOUT == action) | 493 | if (BOOTSTRAPPER_ACTION_LAYOUT == action) |
| 481 | { | 494 | { |
| @@ -556,6 +569,9 @@ extern "C" HRESULT CorePlan( | |||
| 556 | LogPackages(pUpgradeBundlePackage, pForwardCompatibleBundlePackage, &pEngineState->packages, &pEngineState->registration.relatedBundles, action); | 569 | LogPackages(pUpgradeBundlePackage, pForwardCompatibleBundlePackage, &pEngineState->packages, &pEngineState->registration.relatedBundles, action); |
| 557 | } | 570 | } |
| 558 | 571 | ||
| 572 | hr = PlanSetVariables(action, pEngineState->registration.scope, pEngineState->plan.plannedScope, &pEngineState->variables); | ||
| 573 | ExitOnFailure(hr, "Failed to update plan variables after planning."); | ||
| 574 | |||
| 559 | PlanDump(&pEngineState->plan); | 575 | PlanDump(&pEngineState->plan); |
| 560 | 576 | ||
| 561 | LExit: | 577 | LExit: |
| @@ -1331,7 +1347,7 @@ extern "C" void CoreCleanup( | |||
| 1331 | ExitFunction(); | 1347 | ExitFunction(); |
| 1332 | } | 1348 | } |
| 1333 | 1349 | ||
| 1334 | hr = CorePlan(pEngineState, BOOTSTRAPPER_ACTION_UNINSTALL); | 1350 | hr = CorePlan(pEngineState, BOOTSTRAPPER_ACTION_UNINSTALL, BOOTSTRAPPER_SCOPE_DEFAULT); |
| 1335 | ExitOnFailure(hr, "Plan during cleanup failed"); | 1351 | ExitOnFailure(hr, "Plan during cleanup failed"); |
| 1336 | 1352 | ||
| 1337 | hr = CoreApply(pEngineState, pEngineState->hMessageWindow); | 1353 | hr = CoreApply(pEngineState, pEngineState->hMessageWindow); |
| @@ -1470,6 +1486,14 @@ extern "C" HRESULT CoreParseCommandLine( | |||
| 1470 | { | 1486 | { |
| 1471 | pInternalCommand->fDisableSystemRestore = TRUE; | 1487 | pInternalCommand->fDisableSystemRestore = TRUE; |
| 1472 | } | 1488 | } |
| 1489 | else if (CSTR_EQUAL == ::CompareStringOrdinal(&argv[i][1], -1, L"peruser", -1, TRUE)) | ||
| 1490 | { | ||
| 1491 | pCommand->commandLineScope = BOOTSTRAPPER_SCOPE_PER_USER; | ||
| 1492 | } | ||
| 1493 | else if (CSTR_EQUAL == ::CompareStringOrdinal(&argv[i][1], -1, L"permachine", -1, TRUE)) | ||
| 1494 | { | ||
| 1495 | pCommand->commandLineScope = BOOTSTRAPPER_SCOPE_PER_MACHINE; | ||
| 1496 | } | ||
| 1473 | else if (CSTR_EQUAL == ::CompareStringOrdinal(&argv[i][1], -1, L"originalsource", -1, TRUE)) | 1497 | else if (CSTR_EQUAL == ::CompareStringOrdinal(&argv[i][1], -1, L"originalsource", -1, TRUE)) |
| 1474 | { | 1498 | { |
| 1475 | if (i + 1 >= argc) | 1499 | if (i + 1 >= argc) |
| @@ -2346,7 +2370,7 @@ static void LogPackages( | |||
| 2346 | LogRollbackBoundary(pPackage->pRollbackBoundaryBackward); | 2370 | LogRollbackBoundary(pPackage->pRollbackBoundaryBackward); |
| 2347 | } | 2371 | } |
| 2348 | 2372 | ||
| 2349 | LogId(REPORT_STANDARD, MSG_PLANNED_PACKAGE, pPackage->sczId, LoggingPackageStateToString(pPackage->currentState), LoggingRequestStateToString(pPackage->defaultRequested), LoggingRequestStateToString(pPackage->requested), LoggingActionStateToString(pPackage->execute), LoggingActionStateToString(pPackage->rollback), LoggingCacheTypeToString(pPackage->authoredCacheType), LoggingCacheTypeToString(pPackage->cacheType), LoggingPlannedCacheToString(pPackage), LoggingBoolToString(pPackage->fPlannedUncache), LoggingDependencyActionToString(pPackage->dependencyExecute), LoggingPackageRegistrationStateToString(pPackage->fCanAffectRegistration, pPackage->expectedInstallRegistrationState), LoggingPackageRegistrationStateToString(pPackage->fCanAffectRegistration, pPackage->expectedCacheRegistrationState)); | 2373 | LogId(REPORT_STANDARD, MSG_PLANNED_PACKAGE, pPackage->sczId, LoggingPackageStateToString(pPackage->currentState), LoggingRequestStateToString(pPackage->defaultRequested), LoggingRequestStateToString(pPackage->requested), LoggingActionStateToString(pPackage->execute), LoggingActionStateToString(pPackage->rollback), LoggingCacheTypeToString(pPackage->authoredCacheType), LoggingCacheTypeToString(pPackage->cacheType), LoggingPlannedCacheToString(pPackage), LoggingBoolToString(pPackage->fPlannedUncache), LoggingDependencyActionToString(pPackage->dependencyExecute), LoggingPackageRegistrationStateToString(pPackage->fCanAffectRegistration, pPackage->expectedInstallRegistrationState), LoggingPackageRegistrationStateToString(pPackage->fCanAffectRegistration, pPackage->expectedCacheRegistrationState), LoggingInstallScopeToString(pPackage->fPerMachine)); |
| 2350 | 2374 | ||
| 2351 | if (BURN_PACKAGE_TYPE_MSI == pPackage->type) | 2375 | if (BURN_PACKAGE_TYPE_MSI == pPackage->type) |
| 2352 | { | 2376 | { |
diff --git a/src/burn/engine/core.h b/src/burn/engine/core.h index cf615e35..75c0c941 100644 --- a/src/burn/engine/core.h +++ b/src/burn/engine/core.h | |||
| @@ -45,7 +45,9 @@ const LPCWSTR BURN_BUNDLE_EXECUTE_PACKAGE_ACTION = L"WixBundleExecutePackageActi | |||
| 45 | const LPCWSTR BURN_BUNDLE_FORCED_RESTART_PACKAGE = L"WixBundleForcedRestartPackage"; | 45 | const LPCWSTR BURN_BUNDLE_FORCED_RESTART_PACKAGE = L"WixBundleForcedRestartPackage"; |
| 46 | const LPCWSTR BURN_BUNDLE_INSTALLED = L"WixBundleInstalled"; | 46 | const LPCWSTR BURN_BUNDLE_INSTALLED = L"WixBundleInstalled"; |
| 47 | const LPCWSTR BURN_BUNDLE_ELEVATED = L"WixBundleElevated"; | 47 | const LPCWSTR BURN_BUNDLE_ELEVATED = L"WixBundleElevated"; |
| 48 | const LPCWSTR BURN_BUNDLE_PLANNED_SCOPE = L"WixBundlePlannedScope"; | ||
| 48 | const LPCWSTR BURN_BUNDLE_PROVIDER_KEY = L"WixBundleProviderKey"; | 49 | const LPCWSTR BURN_BUNDLE_PROVIDER_KEY = L"WixBundleProviderKey"; |
| 50 | const LPCWSTR BURN_BUNDLE_SCOPE = L"WixBundleScope"; | ||
| 49 | const LPCWSTR BURN_BUNDLE_SOURCE_PROCESS_PATH = L"WixBundleSourceProcessPath"; | 51 | const LPCWSTR BURN_BUNDLE_SOURCE_PROCESS_PATH = L"WixBundleSourceProcessPath"; |
| 50 | const LPCWSTR BURN_BUNDLE_SOURCE_PROCESS_FOLDER = L"WixBundleSourceProcessFolder"; | 52 | const LPCWSTR BURN_BUNDLE_SOURCE_PROCESS_FOLDER = L"WixBundleSourceProcessFolder"; |
| 51 | const LPCWSTR BURN_BUNDLE_TAG = L"WixBundleTag"; | 53 | const LPCWSTR BURN_BUNDLE_TAG = L"WixBundleTag"; |
| @@ -243,7 +245,8 @@ HRESULT CoreDetect( | |||
| 243 | ); | 245 | ); |
| 244 | HRESULT CorePlan( | 246 | HRESULT CorePlan( |
| 245 | __in BURN_ENGINE_STATE* pEngineState, | 247 | __in BURN_ENGINE_STATE* pEngineState, |
| 246 | __in BOOTSTRAPPER_ACTION action | 248 | __in BOOTSTRAPPER_ACTION action, |
| 249 | __in BOOTSTRAPPER_SCOPE scope | ||
| 247 | ); | 250 | ); |
| 248 | HRESULT CoreElevate( | 251 | HRESULT CoreElevate( |
| 249 | __in BURN_ENGINE_STATE* pEngineState, | 252 | __in BURN_ENGINE_STATE* pEngineState, |
diff --git a/src/burn/engine/dependency.cpp b/src/burn/engine/dependency.cpp index 94a8a1e4..7cd0db9f 100644 --- a/src/burn/engine/dependency.cpp +++ b/src/burn/engine/dependency.cpp | |||
| @@ -12,6 +12,7 @@ const LPCWSTR vcszIgnoreDependenciesDelim = L";"; | |||
| 12 | 12 | ||
| 13 | static HRESULT DetectPackageDependents( | 13 | static HRESULT DetectPackageDependents( |
| 14 | __in BURN_PACKAGE* pPackage, | 14 | __in BURN_PACKAGE* pPackage, |
| 15 | __in BOOL fPackagePerMachine, | ||
| 15 | __in const BURN_REGISTRATION* pRegistration | 16 | __in const BURN_REGISTRATION* pRegistration |
| 16 | ); | 17 | ); |
| 17 | 18 | ||
| @@ -249,7 +250,22 @@ extern "C" HRESULT DependencyDetectProviderKeyBundleCode( | |||
| 249 | { | 250 | { |
| 250 | HRESULT hr = S_OK; | 251 | HRESULT hr = S_OK; |
| 251 | 252 | ||
| 252 | hr = DepGetProviderInformation(pRegistration->hkRoot, pRegistration->sczProviderKey, &pRegistration->sczDetectedProviderKeyBundleCode, NULL, NULL); | 253 | // For configurable packages, check both scopes because until planning, |
| 254 | // we can't know their planned scope. | ||
| 255 | if (pRegistration->hkRoot) | ||
| 256 | { | ||
| 257 | hr = DepGetProviderInformation(pRegistration->hkRoot, pRegistration->sczProviderKey, &pRegistration->sczDetectedProviderKeyBundleCode, NULL, NULL); | ||
| 258 | } | ||
| 259 | else | ||
| 260 | { | ||
| 261 | hr = DepGetProviderInformation(HKEY_LOCAL_MACHINE, pRegistration->sczProviderKey, &pRegistration->sczDetectedProviderKeyBundleCode, NULL, NULL); | ||
| 262 | |||
| 263 | if (E_NOTFOUND == hr) | ||
| 264 | { | ||
| 265 | hr = DepGetProviderInformation(HKEY_CURRENT_USER, pRegistration->sczProviderKey, &pRegistration->sczDetectedProviderKeyBundleCode, NULL, NULL); | ||
| 266 | } | ||
| 267 | } | ||
| 268 | |||
| 253 | if (E_NOTFOUND == hr) | 269 | if (E_NOTFOUND == hr) |
| 254 | { | 270 | { |
| 255 | ReleaseNullStr(pRegistration->sczDetectedProviderKeyBundleCode); | 271 | ReleaseNullStr(pRegistration->sczDetectedProviderKeyBundleCode); |
| @@ -284,7 +300,21 @@ extern "C" HRESULT DependencyDetectBundle( | |||
| 284 | hr = DependencyDetectProviderKeyBundleCode(pRegistration); | 300 | hr = DependencyDetectProviderKeyBundleCode(pRegistration); |
| 285 | ExitOnFailure(hr, "Failed to detect provider key bundle code."); | 301 | ExitOnFailure(hr, "Failed to detect provider key bundle code."); |
| 286 | 302 | ||
| 287 | hr = DepCheckDependents(pRegistration->hkRoot, pRegistration->sczProviderKey, 0, NULL, &pRegistration->rgDependents, &pRegistration->cDependents); | 303 | // For configurable packages, check both scopes because until planning, |
| 304 | // we can't know their planned scope. | ||
| 305 | if (pRegistration->hkRoot) | ||
| 306 | { | ||
| 307 | hr = DepCheckDependents(pRegistration->hkRoot, pRegistration->sczProviderKey, 0, NULL, &pRegistration->rgDependents, &pRegistration->cDependents); | ||
| 308 | } | ||
| 309 | else | ||
| 310 | { | ||
| 311 | hr = DepCheckDependents(HKEY_LOCAL_MACHINE, pRegistration->sczProviderKey, 0, NULL, &pRegistration->rgDependents, &pRegistration->cDependents); | ||
| 312 | |||
| 313 | if (E_NOTFOUND == hr) | ||
| 314 | { | ||
| 315 | hr = DepCheckDependents(HKEY_CURRENT_USER, pRegistration->sczProviderKey, 0, NULL, &pRegistration->rgDependents, &pRegistration->cDependents); | ||
| 316 | } | ||
| 317 | } | ||
| 288 | ExitOnPathFailure(hr, fExists, "Failed dependents check on bundle."); | 318 | ExitOnPathFailure(hr, fExists, "Failed dependents check on bundle."); |
| 289 | 319 | ||
| 290 | if (pDependencies->fSelfDependent || pDependencies->fActiveParent) | 320 | if (pDependencies->fSelfDependent || pDependencies->fActiveParent) |
| @@ -292,13 +322,13 @@ extern "C" HRESULT DependencyDetectBundle( | |||
| 292 | for (DWORD i = 0; i < pRegistration->cDependents; ++i) | 322 | for (DWORD i = 0; i < pRegistration->cDependents; ++i) |
| 293 | { | 323 | { |
| 294 | DEPENDENCY* pDependent = pRegistration->rgDependents + i; | 324 | DEPENDENCY* pDependent = pRegistration->rgDependents + i; |
| 295 | 325 | ||
| 296 | if (pDependencies->fActiveParent && CSTR_EQUAL == ::CompareStringOrdinal(pDependencies->wzActiveParent, -1, pDependent->sczKey, -1, TRUE)) | 326 | if (pDependent && pDependencies->fActiveParent && CSTR_EQUAL == ::CompareStringOrdinal(pDependencies->wzActiveParent, -1, pDependent->sczKey, -1, TRUE)) |
| 297 | { | 327 | { |
| 298 | pRegistration->fParentRegisteredAsDependent = TRUE; | 328 | pRegistration->fParentRegisteredAsDependent = TRUE; |
| 299 | } | 329 | } |
| 300 | 330 | ||
| 301 | if (pDependencies->fSelfDependent && CSTR_EQUAL == ::CompareStringOrdinal(pDependencies->wzSelfDependent, -1, pDependent->sczKey, -1, TRUE)) | 331 | if (pDependent && pDependencies->fSelfDependent && CSTR_EQUAL == ::CompareStringOrdinal(pDependencies->wzSelfDependent, -1, pDependent->sczKey, -1, TRUE)) |
| 302 | { | 332 | { |
| 303 | pRegistration->fSelfRegisteredAsDependent = TRUE; | 333 | pRegistration->fSelfRegisteredAsDependent = TRUE; |
| 304 | } | 334 | } |
| @@ -316,11 +346,24 @@ extern "C" HRESULT DependencyDetectChainPackage( | |||
| 316 | { | 346 | { |
| 317 | HRESULT hr = S_OK; | 347 | HRESULT hr = S_OK; |
| 318 | 348 | ||
| 319 | hr = DetectPackageDependents(pPackage, pRegistration); | 349 | if (BOOTSTRAPPER_PACKAGE_SCOPE_PER_USER_OR_PER_MACHINE == pPackage->scope || BOOTSTRAPPER_PACKAGE_SCOPE_PER_MACHINE_OR_PER_USER == pPackage->scope) |
| 320 | ExitOnFailure(hr, "Failed to detect dependents for package '%ls'", pPackage->sczId); | 350 | { |
| 351 | // For configurable packages, check both scopes because until planning, | ||
| 352 | // we can't know their planned scope. | ||
| 353 | hr = DetectPackageDependents(pPackage, /*fPerMachine*/TRUE, pRegistration); | ||
| 354 | ExitOnFailure(hr, "Failed to detect per-machine dependents for configurable package '%ls'", pPackage->sczId); | ||
| 355 | |||
| 356 | hr = DetectPackageDependents(pPackage, /*fPerMachine*/FALSE, pRegistration); | ||
| 357 | ExitOnFailure(hr, "Failed to detect per-user dependents for configurable package '%ls'", pPackage->sczId); | ||
| 358 | } | ||
| 359 | else | ||
| 360 | { | ||
| 361 | hr = DetectPackageDependents(pPackage, pPackage->fPerMachine, pRegistration); | ||
| 362 | ExitOnFailure(hr, "Failed to detect dependents for %hs package '%ls'", LoggingInstallScopeToString(pPackage->fPerMachine), pPackage->sczId); | ||
| 363 | } | ||
| 321 | 364 | ||
| 322 | hr = DependencyDetectCompatibleEntry(pPackage, pRegistration); | 365 | hr = DependencyDetectCompatibleEntry(pPackage, pRegistration); |
| 323 | ExitOnFailure(hr, "Failed to detect compatible package for package '%ls'", pPackage->sczId); | 366 | ExitOnFailure(hr, "Failed to detect compatible package for %hs package '%ls'", LoggingInstallScopeToString(pPackage->fPerMachine), pPackage->sczId); |
| 324 | 367 | ||
| 325 | LExit: | 368 | LExit: |
| 326 | return hr; | 369 | return hr; |
| @@ -336,7 +379,7 @@ extern "C" HRESULT DependencyDetectRelatedBundle( | |||
| 336 | 379 | ||
| 337 | if (pRelatedBundle->fPlannable) | 380 | if (pRelatedBundle->fPlannable) |
| 338 | { | 381 | { |
| 339 | hr = DetectPackageDependents(pPackage, pRegistration); | 382 | hr = DetectPackageDependents(pPackage, pPackage->fPerMachine, pRegistration); |
| 340 | ExitOnFailure(hr, "Failed to detect dependents for related bundle '%ls'", pPackage->sczId); | 383 | ExitOnFailure(hr, "Failed to detect dependents for related bundle '%ls'", pPackage->sczId); |
| 341 | } | 384 | } |
| 342 | 385 | ||
| @@ -626,7 +669,7 @@ LExit: | |||
| 626 | } | 669 | } |
| 627 | 670 | ||
| 628 | extern "C" HRESULT DependencyPlanPackage( | 671 | extern "C" HRESULT DependencyPlanPackage( |
| 629 | __in_opt DWORD *pdwInsertSequence, | 672 | __in_opt DWORD* pdwInsertSequence, |
| 630 | __in const BURN_PACKAGE* pPackage, | 673 | __in const BURN_PACKAGE* pPackage, |
| 631 | __in BURN_PLAN* pPlan | 674 | __in BURN_PLAN* pPlan |
| 632 | ) | 675 | ) |
| @@ -946,18 +989,19 @@ LExit: | |||
| 946 | 989 | ||
| 947 | static HRESULT DetectPackageDependents( | 990 | static HRESULT DetectPackageDependents( |
| 948 | __in BURN_PACKAGE* pPackage, | 991 | __in BURN_PACKAGE* pPackage, |
| 992 | __in BOOL fPackagePerMachine, | ||
| 949 | __in const BURN_REGISTRATION* pRegistration | 993 | __in const BURN_REGISTRATION* pRegistration |
| 950 | ) | 994 | ) |
| 951 | { | 995 | { |
| 952 | HRESULT hr = S_OK; | 996 | HRESULT hr = S_OK; |
| 953 | HKEY hkHive = pPackage->fPerMachine ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; | 997 | HKEY hkHive = fPackagePerMachine ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; |
| 954 | BOOL fCanIgnorePresence = pPackage->fCanAffectRegistration && 0 < pPackage->cDependencyProviders && | 998 | BOOL fCanIgnorePresence = pPackage->fCanAffectRegistration && 0 < pPackage->cDependencyProviders && |
| 955 | (BURN_PACKAGE_REGISTRATION_STATE_PRESENT == pPackage->cacheRegistrationState || BURN_PACKAGE_REGISTRATION_STATE_PRESENT == pPackage->installRegistrationState); | 999 | (BURN_PACKAGE_REGISTRATION_STATE_PRESENT == pPackage->cacheRegistrationState || BURN_PACKAGE_REGISTRATION_STATE_PRESENT == pPackage->installRegistrationState); |
| 956 | BOOL fBundleRegisteredAsDependent = FALSE; | 1000 | BOOL fBundleRegisteredAsDependent = FALSE; |
| 957 | 1001 | ||
| 958 | // There's currently no point in getting the dependents if the scope doesn't match, | 1002 | // There's currently no point in getting the dependents if the scope doesn't match, |
| 959 | // because they will just get ignored. | 1003 | // because they will just get ignored. |
| 960 | if (pRegistration->fPerMachine != pPackage->fPerMachine) | 1004 | if (pRegistration->fPerMachine != fPackagePerMachine) |
| 961 | { | 1005 | { |
| 962 | ExitFunction(); | 1006 | ExitFunction(); |
| 963 | } | 1007 | } |
| @@ -979,7 +1023,7 @@ static HRESULT DetectPackageDependents( | |||
| 979 | { | 1023 | { |
| 980 | DEPENDENCY* pDependent = pProvider->rgDependents + iDependent; | 1024 | DEPENDENCY* pDependent = pProvider->rgDependents + iDependent; |
| 981 | 1025 | ||
| 982 | if (CSTR_EQUAL == ::CompareStringOrdinal(pRegistration->sczCode, -1, pDependent->sczKey, -1, TRUE)) | 1026 | if (pDependent && CSTR_EQUAL == ::CompareStringOrdinal(pRegistration->sczCode, -1, pDependent->sczKey, -1, TRUE)) |
| 983 | { | 1027 | { |
| 984 | pProvider->fBundleRegisteredAsDependent = TRUE; | 1028 | pProvider->fBundleRegisteredAsDependent = TRUE; |
| 985 | fBundleRegisteredAsDependent = TRUE; | 1029 | fBundleRegisteredAsDependent = TRUE; |
| @@ -994,10 +1038,12 @@ static HRESULT DetectPackageDependents( | |||
| 994 | { | 1038 | { |
| 995 | pPackage->cacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_IGNORED; | 1039 | pPackage->cacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_IGNORED; |
| 996 | } | 1040 | } |
| 1041 | |||
| 997 | if (BURN_PACKAGE_REGISTRATION_STATE_PRESENT == pPackage->installRegistrationState) | 1042 | if (BURN_PACKAGE_REGISTRATION_STATE_PRESENT == pPackage->installRegistrationState) |
| 998 | { | 1043 | { |
| 999 | pPackage->installRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_IGNORED; | 1044 | pPackage->installRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_IGNORED; |
| 1000 | } | 1045 | } |
| 1046 | |||
| 1001 | if (BURN_PACKAGE_TYPE_MSP == pPackage->type) | 1047 | if (BURN_PACKAGE_TYPE_MSP == pPackage->type) |
| 1002 | { | 1048 | { |
| 1003 | for (DWORD i = 0; i < pPackage->Msp.cTargetProductCodes; ++i) | 1049 | for (DWORD i = 0; i < pPackage->Msp.cTargetProductCodes; ++i) |
diff --git a/src/burn/engine/elevation.cpp b/src/burn/engine/elevation.cpp index ef87841f..711ce4af 100644 --- a/src/burn/engine/elevation.cpp +++ b/src/burn/engine/elevation.cpp | |||
| @@ -1191,7 +1191,6 @@ extern "C" HRESULT ElevationExecuteMsiPackage( | |||
| 1191 | hr = VariableSerialize(pVariables, FALSE, &pbData, &cbData); | 1191 | hr = VariableSerialize(pVariables, FALSE, &pbData, &cbData); |
| 1192 | ExitOnFailure(hr, "Failed to write variables."); | 1192 | ExitOnFailure(hr, "Failed to write variables."); |
| 1193 | 1193 | ||
| 1194 | |||
| 1195 | // send message | 1194 | // send message |
| 1196 | context.pfnMessageHandler = pfnMessageHandler; | 1195 | context.pfnMessageHandler = pfnMessageHandler; |
| 1197 | context.pvContext = pvContext; | 1196 | context.pvContext = pvContext; |
| @@ -2572,6 +2571,11 @@ static HRESULT OnSessionBegin( | |||
| 2572 | ExitOnFailure(hr, "Failed to read variables."); | 2571 | ExitOnFailure(hr, "Failed to read variables."); |
| 2573 | 2572 | ||
| 2574 | // Begin session in per-machine process. | 2573 | // Begin session in per-machine process. |
| 2574 | pRegistration->fPerMachine = TRUE; | ||
| 2575 | |||
| 2576 | hr = RegistrationSetPaths(pRegistration, pCache); | ||
| 2577 | ExitOnFailure(hr, "Failed to set elevated registration paths."); | ||
| 2578 | |||
| 2575 | hr = RegistrationSessionBegin(sczEngineWorkingPath, pRegistration, pCache, pVariables, dwRegistrationOperations, qwEstimatedSize, (BOOTSTRAPPER_REGISTRATION_TYPE)dwRegistrationType); | 2579 | hr = RegistrationSessionBegin(sczEngineWorkingPath, pRegistration, pCache, pVariables, dwRegistrationOperations, qwEstimatedSize, (BOOTSTRAPPER_REGISTRATION_TYPE)dwRegistrationType); |
| 2576 | ExitOnFailure(hr, "Failed to begin registration session."); | 2580 | ExitOnFailure(hr, "Failed to begin registration session."); |
| 2577 | 2581 | ||
| @@ -2657,6 +2661,8 @@ static HRESULT OnCachePreparePackage( | |||
| 2657 | { | 2661 | { |
| 2658 | hr = PackageFindById(pPackages, scz, &pPackage); | 2662 | hr = PackageFindById(pPackages, scz, &pPackage); |
| 2659 | ExitOnFailure(hr, "Failed to find package: %ls", scz); | 2663 | ExitOnFailure(hr, "Failed to find package: %ls", scz); |
| 2664 | |||
| 2665 | pPackage->fPerMachine = TRUE; | ||
| 2660 | } | 2666 | } |
| 2661 | else | 2667 | else |
| 2662 | { | 2668 | { |
| @@ -2698,6 +2704,8 @@ static HRESULT OnCacheCompletePayload( | |||
| 2698 | { | 2704 | { |
| 2699 | hr = PackageFindById(pPackages, scz, &pPackage); | 2705 | hr = PackageFindById(pPackages, scz, &pPackage); |
| 2700 | ExitOnFailure(hr, "Failed to find package: %ls", scz); | 2706 | ExitOnFailure(hr, "Failed to find package: %ls", scz); |
| 2707 | |||
| 2708 | pPackage->fPerMachine = TRUE; | ||
| 2701 | } | 2709 | } |
| 2702 | 2710 | ||
| 2703 | hr = BuffReadString(pbData, cbData, &iData, &scz); | 2711 | hr = BuffReadString(pbData, cbData, &iData, &scz); |
| @@ -2717,8 +2725,8 @@ static HRESULT OnCacheCompletePayload( | |||
| 2717 | 2725 | ||
| 2718 | if (pPackage && pPayload) // complete payload. | 2726 | if (pPackage && pPayload) // complete payload. |
| 2719 | { | 2727 | { |
| 2720 | hr = CacheCompletePayload(pCache, pPackage->fPerMachine, pPayload, pPackage->sczCacheId, sczUnverifiedPath, fMove, BurnCacheMessageHandler, ElevatedProgressRoutine, hPipe); | 2728 | hr = CacheCompletePayload(pCache, TRUE/*fPerMachine*/, pPayload, pPackage->sczCacheId, sczUnverifiedPath, fMove, BurnCacheMessageHandler, ElevatedProgressRoutine, hPipe); |
| 2721 | ExitOnFailure(hr, "Failed to cache payload: %ls", pPayload->sczKey); | 2729 | ExitOnFailure(hr, "Failed to cache per-machine payload: %ls", pPayload->sczKey); |
| 2722 | } | 2730 | } |
| 2723 | else | 2731 | else |
| 2724 | { | 2732 | { |
| @@ -2755,6 +2763,8 @@ static HRESULT OnCacheVerifyPayload( | |||
| 2755 | { | 2763 | { |
| 2756 | hr = PackageFindById(pPackages, scz, &pPackage); | 2764 | hr = PackageFindById(pPackages, scz, &pPackage); |
| 2757 | ExitOnFailure(hr, "Failed to find package: %ls", scz); | 2765 | ExitOnFailure(hr, "Failed to find package: %ls", scz); |
| 2766 | |||
| 2767 | pPackage->fPerMachine = TRUE; | ||
| 2758 | } | 2768 | } |
| 2759 | 2769 | ||
| 2760 | hr = BuffReadString(pbData, cbData, &iData, &scz); | 2770 | hr = BuffReadString(pbData, cbData, &iData, &scz); |
| @@ -2970,6 +2980,8 @@ static HRESULT OnExecuteBundlePackage( | |||
| 2970 | hr = PackageFindById(pPackages, sczPackage, &executeAction.bundlePackage.pPackage); | 2980 | hr = PackageFindById(pPackages, sczPackage, &executeAction.bundlePackage.pPackage); |
| 2971 | ExitOnFailure(hr, "Failed to find package: %ls", sczPackage); | 2981 | ExitOnFailure(hr, "Failed to find package: %ls", sczPackage); |
| 2972 | 2982 | ||
| 2983 | executeAction.bundlePackage.pPackage->fPerMachine = TRUE; | ||
| 2984 | |||
| 2973 | if (BURN_PACKAGE_TYPE_BUNDLE != executeAction.bundlePackage.pPackage->type) | 2985 | if (BURN_PACKAGE_TYPE_BUNDLE != executeAction.bundlePackage.pPackage->type) |
| 2974 | { | 2986 | { |
| 2975 | ExitWithRootFailure(hr, E_INVALIDARG, "Package is not a BUNDLE package: %ls", sczPackage); | 2987 | ExitWithRootFailure(hr, E_INVALIDARG, "Package is not a BUNDLE package: %ls", sczPackage); |
| @@ -3052,6 +3064,8 @@ static HRESULT OnExecuteExePackage( | |||
| 3052 | hr = PackageFindById(pPackages, sczPackage, &executeAction.exePackage.pPackage); | 3064 | hr = PackageFindById(pPackages, sczPackage, &executeAction.exePackage.pPackage); |
| 3053 | ExitOnFailure(hr, "Failed to find package: %ls", sczPackage); | 3065 | ExitOnFailure(hr, "Failed to find package: %ls", sczPackage); |
| 3054 | 3066 | ||
| 3067 | executeAction.exePackage.pPackage->fPerMachine = TRUE; | ||
| 3068 | |||
| 3055 | if (BURN_PACKAGE_TYPE_EXE != executeAction.exePackage.pPackage->type) | 3069 | if (BURN_PACKAGE_TYPE_EXE != executeAction.exePackage.pPackage->type) |
| 3056 | { | 3070 | { |
| 3057 | ExitWithRootFailure(hr, E_INVALIDARG, "Package is not an EXE package: %ls", sczPackage); | 3071 | ExitWithRootFailure(hr, E_INVALIDARG, "Package is not an EXE package: %ls", sczPackage); |
| @@ -3113,6 +3127,8 @@ static HRESULT OnExecuteMsiPackage( | |||
| 3113 | hr = PackageFindById(pPackages, sczPackage, &executeAction.msiPackage.pPackage); | 3127 | hr = PackageFindById(pPackages, sczPackage, &executeAction.msiPackage.pPackage); |
| 3114 | ExitOnFailure(hr, "Failed to find package: %ls", sczPackage); | 3128 | ExitOnFailure(hr, "Failed to find package: %ls", sczPackage); |
| 3115 | 3129 | ||
| 3130 | executeAction.msiPackage.pPackage->fPerMachine = TRUE; | ||
| 3131 | |||
| 3116 | hr = BuffReadPointer(pbData, cbData, &iData, (DWORD_PTR*)&hwndParent); | 3132 | hr = BuffReadPointer(pbData, cbData, &iData, (DWORD_PTR*)&hwndParent); |
| 3117 | ExitOnFailure(hr, "Failed to read parent hwnd."); | 3133 | ExitOnFailure(hr, "Failed to read parent hwnd."); |
| 3118 | 3134 | ||
| @@ -3205,6 +3221,8 @@ static HRESULT OnExecuteMspPackage( | |||
| 3205 | hr = PackageFindById(pPackages, sczPackage, &executeAction.mspTarget.pPackage); | 3221 | hr = PackageFindById(pPackages, sczPackage, &executeAction.mspTarget.pPackage); |
| 3206 | ExitOnFailure(hr, "Failed to find package: %ls", sczPackage); | 3222 | ExitOnFailure(hr, "Failed to find package: %ls", sczPackage); |
| 3207 | 3223 | ||
| 3224 | executeAction.mspTarget.pPackage->fPerMachine = TRUE; | ||
| 3225 | |||
| 3208 | hr = BuffReadPointer(pbData, cbData, &iData, (DWORD_PTR*)&hwndParent); | 3226 | hr = BuffReadPointer(pbData, cbData, &iData, (DWORD_PTR*)&hwndParent); |
| 3209 | ExitOnFailure(hr, "Failed to read parent hwnd."); | 3227 | ExitOnFailure(hr, "Failed to read parent hwnd."); |
| 3210 | 3228 | ||
| @@ -3246,6 +3264,8 @@ static HRESULT OnExecuteMspPackage( | |||
| 3246 | 3264 | ||
| 3247 | hr = PackageFindById(pPackages, sczPackage, &executeAction.mspTarget.rgOrderedPatches[i].pPackage); | 3265 | hr = PackageFindById(pPackages, sczPackage, &executeAction.mspTarget.rgOrderedPatches[i].pPackage); |
| 3248 | ExitOnFailure(hr, "Failed to find ordered patch package: %ls", sczPackage); | 3266 | ExitOnFailure(hr, "Failed to find ordered patch package: %ls", sczPackage); |
| 3267 | |||
| 3268 | executeAction.mspTarget.rgOrderedPatches[i].pPackage->fPerMachine = TRUE; | ||
| 3249 | } | 3269 | } |
| 3250 | } | 3270 | } |
| 3251 | 3271 | ||
| @@ -3310,6 +3330,8 @@ static HRESULT OnExecuteMsuPackage( | |||
| 3310 | hr = PackageFindById(pPackages, sczPackage, &executeAction.msuPackage.pPackage); | 3330 | hr = PackageFindById(pPackages, sczPackage, &executeAction.msuPackage.pPackage); |
| 3311 | ExitOnFailure(hr, "Failed to find package: %ls", sczPackage); | 3331 | ExitOnFailure(hr, "Failed to find package: %ls", sczPackage); |
| 3312 | 3332 | ||
| 3333 | executeAction.msuPackage.pPackage->fPerMachine = TRUE; | ||
| 3334 | |||
| 3313 | if (BURN_PACKAGE_TYPE_MSU != executeAction.msuPackage.pPackage->type) | 3335 | if (BURN_PACKAGE_TYPE_MSU != executeAction.msuPackage.pPackage->type) |
| 3314 | { | 3336 | { |
| 3315 | ExitWithRootFailure(hr, E_INVALIDARG, "Package is not an MSU package: %ls", sczPackage); | 3337 | ExitWithRootFailure(hr, E_INVALIDARG, "Package is not an MSU package: %ls", sczPackage); |
| @@ -3371,6 +3393,8 @@ static HRESULT OnUninstallMsiCompatiblePackage( | |||
| 3371 | hr = PackageFindById(pPackages, sczPackageId, &pPackage); | 3393 | hr = PackageFindById(pPackages, sczPackageId, &pPackage); |
| 3372 | ExitOnFailure(hr, "Failed to find package: %ls", sczPackageId); | 3394 | ExitOnFailure(hr, "Failed to find package: %ls", sczPackageId); |
| 3373 | 3395 | ||
| 3396 | pPackage->fPerMachine = TRUE; | ||
| 3397 | |||
| 3374 | executeAction.uninstallMsiCompatiblePackage.pParentPackage = pPackage; | 3398 | executeAction.uninstallMsiCompatiblePackage.pParentPackage = pPackage; |
| 3375 | pCompatiblePackage = &pPackage->compatiblePackage; | 3399 | pCompatiblePackage = &pPackage->compatiblePackage; |
| 3376 | 3400 | ||
| @@ -3424,6 +3448,8 @@ static HRESULT OnExecutePackageProviderAction( | |||
| 3424 | } | 3448 | } |
| 3425 | ExitOnFailure(hr, "Failed to find package: %ls", sczPackage); | 3449 | ExitOnFailure(hr, "Failed to find package: %ls", sczPackage); |
| 3426 | 3450 | ||
| 3451 | executeAction.packageProvider.pPackage->fPerMachine; | ||
| 3452 | |||
| 3427 | hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&fRollback); | 3453 | hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&fRollback); |
| 3428 | ExitOnFailure(hr, "Failed to read rollback flag."); | 3454 | ExitOnFailure(hr, "Failed to read rollback flag."); |
| 3429 | 3455 | ||
| @@ -3436,11 +3462,6 @@ static HRESULT OnExecutePackageProviderAction( | |||
| 3436 | ExitOnFailure(hr, "Failed to read provider action."); | 3462 | ExitOnFailure(hr, "Failed to read provider action."); |
| 3437 | } | 3463 | } |
| 3438 | 3464 | ||
| 3439 | if (!executeAction.packageProvider.pPackage->fPerMachine) | ||
| 3440 | { | ||
| 3441 | ExitWithRootFailure(hr, E_INVALIDARG, "ExecutePackageProviderAction called for per-user package."); | ||
| 3442 | } | ||
| 3443 | |||
| 3444 | // Execute the package provider action. | 3465 | // Execute the package provider action. |
| 3445 | hr = DependencyExecutePackageProviderAction(&executeAction, fRollback); | 3466 | hr = DependencyExecutePackageProviderAction(&executeAction, fRollback); |
| 3446 | ExitOnFailure(hr, "Failed to execute package provider action."); | 3467 | ExitOnFailure(hr, "Failed to execute package provider action."); |
| @@ -3479,6 +3500,8 @@ static HRESULT OnExecutePackageDependencyAction( | |||
| 3479 | } | 3500 | } |
| 3480 | ExitOnFailure(hr, "Failed to find package: %ls", sczPackage); | 3501 | ExitOnFailure(hr, "Failed to find package: %ls", sczPackage); |
| 3481 | 3502 | ||
| 3503 | executeAction.packageDependency.pPackage->fPerMachine = TRUE; | ||
| 3504 | |||
| 3482 | hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&fRollback); | 3505 | hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&fRollback); |
| 3483 | ExitOnFailure(hr, "Failed to read rollback flag."); | 3506 | ExitOnFailure(hr, "Failed to read rollback flag."); |
| 3484 | 3507 | ||
| @@ -3784,6 +3807,8 @@ static HRESULT OnCleanCompatiblePackage( | |||
| 3784 | hr = PackageFindById(pPackages, sczPackageId, &pPackage); | 3807 | hr = PackageFindById(pPackages, sczPackageId, &pPackage); |
| 3785 | ExitOnFailure(hr, "Failed to find package: %ls", sczPackageId); | 3808 | ExitOnFailure(hr, "Failed to find package: %ls", sczPackageId); |
| 3786 | 3809 | ||
| 3810 | pPackage->fPerMachine = TRUE; | ||
| 3811 | |||
| 3787 | pCompatiblePackage = &pPackage->compatiblePackage; | 3812 | pCompatiblePackage = &pPackage->compatiblePackage; |
| 3788 | 3813 | ||
| 3789 | if (!pCompatiblePackage->fDetected || !pCompatiblePackage->compatibleEntry.sczId || !pCompatiblePackage->sczCacheId || !*pCompatiblePackage->sczCacheId) | 3814 | if (!pCompatiblePackage->fDetected || !pCompatiblePackage->compatibleEntry.sczId || !pCompatiblePackage->sczCacheId || !*pCompatiblePackage->sczCacheId) |
| @@ -3826,6 +3851,8 @@ static HRESULT OnCleanPackage( | |||
| 3826 | hr = PackageFindById(pPackages, sczPackage, &pPackage); | 3851 | hr = PackageFindById(pPackages, sczPackage, &pPackage); |
| 3827 | ExitOnFailure(hr, "Failed to find package: %ls", sczPackage); | 3852 | ExitOnFailure(hr, "Failed to find package: %ls", sczPackage); |
| 3828 | 3853 | ||
| 3854 | pPackage->fPerMachine = TRUE; | ||
| 3855 | |||
| 3829 | // Remove the package from the cache. | 3856 | // Remove the package from the cache. |
| 3830 | hr = CacheRemovePackage(pCache, TRUE, pPackage->sczId, pPackage->sczCacheId); | 3857 | hr = CacheRemovePackage(pCache, TRUE, pPackage->sczId, pPackage->sczCacheId); |
| 3831 | ExitOnFailure(hr, "Failed to remove from cache package: %ls", pPackage->sczId); | 3858 | ExitOnFailure(hr, "Failed to remove from cache package: %ls", pPackage->sczId); |
diff --git a/src/burn/engine/engine.cpp b/src/burn/engine/engine.cpp index d432f732..8423da41 100644 --- a/src/burn/engine/engine.cpp +++ b/src/burn/engine/engine.cpp | |||
| @@ -16,11 +16,6 @@ static HRESULT InitializeEngineState( | |||
| 16 | static void UninitializeEngineState( | 16 | static void UninitializeEngineState( |
| 17 | __in BURN_ENGINE_STATE* pEngineState | 17 | __in BURN_ENGINE_STATE* pEngineState |
| 18 | ); | 18 | ); |
| 19 | #if 0 | ||
| 20 | static HRESULT RunUntrusted( | ||
| 21 | __in BURN_ENGINE_STATE* pEngineState | ||
| 22 | ); | ||
| 23 | #endif | ||
| 24 | static HRESULT RunNormal( | 19 | static HRESULT RunNormal( |
| 25 | __in HINSTANCE hInstance, | 20 | __in HINSTANCE hInstance, |
| 26 | __in BURN_ENGINE_STATE* pEngineState | 21 | __in BURN_ENGINE_STATE* pEngineState |
| @@ -812,7 +807,7 @@ static HRESULT ProcessMessage( | |||
| 812 | break; | 807 | break; |
| 813 | 808 | ||
| 814 | case WM_BURN_PLAN: | 809 | case WM_BURN_PLAN: |
| 815 | hr = CorePlan(pEngineState, pAction->plan.action); | 810 | hr = CorePlan(pEngineState, pAction->plan.action, pAction->plan.plannedScope); |
| 816 | break; | 811 | break; |
| 817 | 812 | ||
| 818 | case WM_BURN_ELEVATE: | 813 | case WM_BURN_ELEVATE: |
diff --git a/src/burn/engine/engine.mc b/src/burn/engine/engine.mc index 776f7832..8e2f1a2e 100644 --- a/src/burn/engine/engine.mc +++ b/src/burn/engine/engine.mc | |||
| @@ -271,7 +271,7 @@ MessageId=101 | |||
| 271 | Severity=Success | 271 | Severity=Success |
| 272 | SymbolicName=MSG_DETECTED_PACKAGE | 272 | SymbolicName=MSG_DETECTED_PACKAGE |
| 273 | Language=English | 273 | Language=English |
| 274 | Detected package: %1!ls!, state: %2!hs!, cached: %3!hs!, install registration state: %4!hs!, cache registration state: %5!hs! | 274 | Detected package: %1!ls!, state: %2!hs!, authored scope: %6!hs!, cached: %3!hs!, install registration state: %4!hs!, cache registration state: %5!hs! |
| 275 | . | 275 | . |
| 276 | 276 | ||
| 277 | MessageId=102 | 277 | MessageId=102 |
| @@ -404,14 +404,21 @@ MessageId=200 | |||
| 404 | Severity=Success | 404 | Severity=Success |
| 405 | SymbolicName=MSG_PLAN_BEGIN | 405 | SymbolicName=MSG_PLAN_BEGIN |
| 406 | Language=English | 406 | Language=English |
| 407 | Plan begin, %1!u! packages, action: %2!hs! | 407 | Plan begin, %1!u! packages, action: %2!hs!, planned scope: %3!hs! |
| 408 | . | ||
| 409 | |||
| 410 | MessageId=226 | ||
| 411 | Severity=Success | ||
| 412 | SymbolicName=MSG_PLAN_CONFIGURED_SCOPE | ||
| 413 | Language=English | ||
| 414 | Planned configurable scope: %1!hs! | ||
| 408 | . | 415 | . |
| 409 | 416 | ||
| 410 | MessageId=201 | 417 | MessageId=201 |
| 411 | Severity=Success | 418 | Severity=Success |
| 412 | SymbolicName=MSG_PLANNED_PACKAGE | 419 | SymbolicName=MSG_PLANNED_PACKAGE |
| 413 | Language=English | 420 | Language=English |
| 414 | Planned package: %1!ls!, state: %2!hs!, default requested: %3!hs!, ba requested: %4!hs!, execute: %5!hs!, rollback: %6!hs!, default cache strategy: %7!hs!, ba requested strategy: %8!hs!, cache: %9!hs!, uncache: %10!hs!, dependency: %11!hs!, expected install registration state: %12!hs!, expected cache registration state: %13!hs! | 421 | Planned package: %1!ls!, state: %2!hs!, default requested: %3!hs!, ba requested: %4!hs!, execute: %5!hs!, rollback: %6!hs!, scope: %14!hs!, default cache strategy: %7!hs!, ba requested strategy: %8!hs!, cache: %9!hs!, uncache: %10!hs!, dependency: %11!hs!, expected install registration state: %12!hs!, expected cache registration state: %13!hs! |
| 415 | . | 422 | . |
| 416 | 423 | ||
| 417 | MessageId=203 | 424 | MessageId=203 |
| @@ -782,7 +789,7 @@ MessageId=328 | |||
| 782 | Severity=Warning | 789 | Severity=Warning |
| 783 | SymbolicName=MSG_DEPENDENCY_PACKAGE_DEPENDENT | 790 | SymbolicName=MSG_DEPENDENCY_PACKAGE_DEPENDENT |
| 784 | Language=English | 791 | Language=English |
| 785 | Found dependent: %1!ls!, name: %2!ls! | 792 | Found dependent: %1!ls!, name: %2!ls! |
| 786 | . | 793 | . |
| 787 | 794 | ||
| 788 | MessageId=329 | 795 | MessageId=329 |
| @@ -1288,3 +1295,17 @@ SymbolicName=MSG_DEPENDENCY_PACKAGE_DEPENDENTS_OVERRIDDEN | |||
| 1288 | Language=English | 1295 | Language=English |
| 1289 | BA requested to uninstall package: %1!ls!, despite dependents: | 1296 | BA requested to uninstall package: %1!ls!, despite dependents: |
| 1290 | . | 1297 | . |
| 1298 | MessageId=702 | ||
| 1299 | Severity=Warning | ||
| 1300 | SymbolicName=MSG_SCOPE_IGNORED_BA_SCOPE | ||
| 1301 | Language=English | ||
| 1302 | Scope command-line switch ignored because the bootstrapper application already specified a scope. | ||
| 1303 | . | ||
| 1304 | |||
| 1305 | MessageId=703 | ||
| 1306 | Severity=Warning | ||
| 1307 | SymbolicName=MSG_SCOPE_IGNORED_UNCONFIGURABLE | ||
| 1308 | Language=English | ||
| 1309 | Scope command-line switch ignored because the bundle doesn't have any packages with configurable scope. | ||
| 1310 | . | ||
| 1311 | |||
diff --git a/src/burn/engine/engine.vcxproj b/src/burn/engine/engine.vcxproj index 98556ea6..5ab9f1ce 100644 --- a/src/burn/engine/engine.vcxproj +++ b/src/burn/engine/engine.vcxproj | |||
| @@ -1,6 +1,5 @@ | |||
| 1 | <?xml version="1.0" encoding="utf-8"?> | 1 | <?xml version="1.0" encoding="utf-8"?> |
| 2 | <!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. --> | 2 | <!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. --> |
| 3 | |||
| 4 | <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | 3 | <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
| 5 | <ItemGroup Label="ProjectConfigurations"> | 4 | <ItemGroup Label="ProjectConfigurations"> |
| 6 | <ProjectConfiguration Include="Debug|Win32"> | 5 | <ProjectConfiguration Include="Debug|Win32"> |
| @@ -28,7 +27,6 @@ | |||
| 28 | <Platform>ARM64</Platform> | 27 | <Platform>ARM64</Platform> |
| 29 | </ProjectConfiguration> | 28 | </ProjectConfiguration> |
| 30 | </ItemGroup> | 29 | </ItemGroup> |
| 31 | |||
| 32 | <PropertyGroup Label="Globals"> | 30 | <PropertyGroup Label="Globals"> |
| 33 | <ProjectGuid>{8119537D-E1D9-6591-D51A-49768A2F9C37}</ProjectGuid> | 31 | <ProjectGuid>{8119537D-E1D9-6591-D51A-49768A2F9C37}</ProjectGuid> |
| 34 | <ConfigurationType>StaticLibrary</ConfigurationType> | 32 | <ConfigurationType>StaticLibrary</ConfigurationType> |
| @@ -37,20 +35,15 @@ | |||
| 37 | <Description>Native component of WixToolset.Burn</Description> | 35 | <Description>Native component of WixToolset.Burn</Description> |
| 38 | <CustomBuildBeforeTargets>ClCompile</CustomBuildBeforeTargets> | 36 | <CustomBuildBeforeTargets>ClCompile</CustomBuildBeforeTargets> |
| 39 | </PropertyGroup> | 37 | </PropertyGroup> |
| 40 | |||
| 41 | <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> | 38 | <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> |
| 42 | <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> | 39 | <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> |
| 43 | |||
| 44 | <PropertyGroup> | 40 | <PropertyGroup> |
| 45 | <ProjectAdditionalIncludeDirectories>..\..\api\burn\inc;$(BurnGeneratedHeaderDirectory);$(ProjectAdditionalIncludeDirectories)</ProjectAdditionalIncludeDirectories> | 41 | <ProjectAdditionalIncludeDirectories>..\..\api\burn\inc;$(BurnGeneratedHeaderDirectory);$(ProjectAdditionalIncludeDirectories)</ProjectAdditionalIncludeDirectories> |
| 46 | </PropertyGroup> | 42 | </PropertyGroup> |
| 47 | |||
| 48 | <ImportGroup Label="ExtensionSettings"> | 43 | <ImportGroup Label="ExtensionSettings"> |
| 49 | </ImportGroup> | 44 | </ImportGroup> |
| 50 | |||
| 51 | <ImportGroup Label="Shared"> | 45 | <ImportGroup Label="Shared"> |
| 52 | </ImportGroup> | 46 | </ImportGroup> |
| 53 | |||
| 54 | <ItemGroup> | 47 | <ItemGroup> |
| 55 | <ClCompile Include="apply.cpp" /> | 48 | <ClCompile Include="apply.cpp" /> |
| 56 | <ClCompile Include="approvedexe.cpp" /> | 49 | <ClCompile Include="approvedexe.cpp" /> |
| @@ -97,7 +90,6 @@ | |||
| 97 | <ClCompile Include="variable.cpp" /> | 90 | <ClCompile Include="variable.cpp" /> |
| 98 | <ClCompile Include="variant.cpp" /> | 91 | <ClCompile Include="variant.cpp" /> |
| 99 | </ItemGroup> | 92 | </ItemGroup> |
| 100 | |||
| 101 | <ItemGroup> | 93 | <ItemGroup> |
| 102 | <ClInclude Include="apply.h" /> | 94 | <ClInclude Include="apply.h" /> |
| 103 | <ClInclude Include="approvedexe.h" /> | 95 | <ClInclude Include="approvedexe.h" /> |
| @@ -147,7 +139,6 @@ | |||
| 147 | <ClInclude Include="variable.h" /> | 139 | <ClInclude Include="variable.h" /> |
| 148 | <ClInclude Include="variant.h" /> | 140 | <ClInclude Include="variant.h" /> |
| 149 | </ItemGroup> | 141 | </ItemGroup> |
| 150 | |||
| 151 | <ItemDefinitionGroup> | 142 | <ItemDefinitionGroup> |
| 152 | <CustomBuildStep> | 143 | <CustomBuildStep> |
| 153 | <Message>Compiling message file...</Message> | 144 | <Message>Compiling message file...</Message> |
| @@ -157,7 +148,6 @@ rc.exe -fo "$(OutDir)engine.res" "$(IntDir)engine.messages.rc"</Command> | |||
| 157 | <Outputs>$(IntDir)engine.messages.h;$(IntDir)engine.messages.rc</Outputs> | 148 | <Outputs>$(IntDir)engine.messages.h;$(IntDir)engine.messages.rc</Outputs> |
| 158 | </CustomBuildStep> | 149 | </CustomBuildStep> |
| 159 | </ItemDefinitionGroup> | 150 | </ItemDefinitionGroup> |
| 160 | |||
| 161 | <Target Name="SetWixVersion" BeforeTargets="ClCompile"> | 151 | <Target Name="SetWixVersion" BeforeTargets="ClCompile"> |
| 162 | <PropertyGroup> | 152 | <PropertyGroup> |
| 163 | <rmj>$(SomeVerInfoMajor)</rmj> | 153 | <rmj>$(SomeVerInfoMajor)</rmj> |
| @@ -172,11 +162,12 @@ rc.exe -fo "$(OutDir)engine.res" "$(IntDir)engine.messages.rc"</Command> | |||
| 172 | </ItemGroup> | 162 | </ItemGroup> |
| 173 | <WriteLinesToFile Overwrite="true" File="$(BurnGeneratedHeaderDirectory)engine.version.h" Lines="@(BurnVersionLines)" /> | 163 | <WriteLinesToFile Overwrite="true" File="$(BurnGeneratedHeaderDirectory)engine.version.h" Lines="@(BurnVersionLines)" /> |
| 174 | </Target> | 164 | </Target> |
| 175 | |||
| 176 | <ItemGroup> | 165 | <ItemGroup> |
| 177 | <PackageReference Include="WixToolset.DUtil" /> | 166 | <PackageReference Include="WixToolset.DUtil" /> |
| 178 | <PackageReference Include="Microsoft.SourceLink.GitHub" PrivateAssets="All" /> | 167 | <PackageReference Include="Microsoft.SourceLink.GitHub" PrivateAssets="All" /> |
| 179 | </ItemGroup> | 168 | </ItemGroup> |
| 180 | 169 | <ItemGroup> | |
| 170 | <None Include="engine.mc" /> | ||
| 171 | </ItemGroup> | ||
| 181 | <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> | 172 | <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> |
| 182 | </Project> | 173 | </Project> \ No newline at end of file |
diff --git a/src/burn/engine/externalengine.cpp b/src/burn/engine/externalengine.cpp index 352d184c..d4814dc1 100644 --- a/src/burn/engine/externalengine.cpp +++ b/src/burn/engine/externalengine.cpp | |||
| @@ -633,8 +633,9 @@ LExit: | |||
| 633 | 633 | ||
| 634 | HRESULT ExternalEnginePlan( | 634 | HRESULT ExternalEnginePlan( |
| 635 | __in BAENGINE_CONTEXT* pEngineContext, | 635 | __in BAENGINE_CONTEXT* pEngineContext, |
| 636 | __in const BOOTSTRAPPER_ACTION action | 636 | __in const BOOTSTRAPPER_ACTION action, |
| 637 | ) | 637 | __in const BOOTSTRAPPER_SCOPE plannedScope |
| 638 | ) | ||
| 638 | { | 639 | { |
| 639 | HRESULT hr = S_OK; | 640 | HRESULT hr = S_OK; |
| 640 | BAENGINE_ACTION* pAction = NULL; | 641 | BAENGINE_ACTION* pAction = NULL; |
| @@ -649,6 +650,7 @@ HRESULT ExternalEnginePlan( | |||
| 649 | 650 | ||
| 650 | pAction->dwMessage = WM_BURN_PLAN; | 651 | pAction->dwMessage = WM_BURN_PLAN; |
| 651 | pAction->plan.action = action; | 652 | pAction->plan.action = action; |
| 653 | pAction->plan.plannedScope = plannedScope; | ||
| 652 | 654 | ||
| 653 | hr = EnqueueAction(pEngineContext, &pAction); | 655 | hr = EnqueueAction(pEngineContext, &pAction); |
| 654 | ExitOnFailure(hr, "Failed to enqueue plan action."); | 656 | ExitOnFailure(hr, "Failed to enqueue plan action."); |
diff --git a/src/burn/engine/externalengine.h b/src/burn/engine/externalengine.h index 9b95e645..1053d0c0 100644 --- a/src/burn/engine/externalengine.h +++ b/src/burn/engine/externalengine.h | |||
| @@ -146,8 +146,9 @@ HRESULT ExternalEngineDetect( | |||
| 146 | 146 | ||
| 147 | HRESULT ExternalEnginePlan( | 147 | HRESULT ExternalEnginePlan( |
| 148 | __in BAENGINE_CONTEXT* pEngineContext, | 148 | __in BAENGINE_CONTEXT* pEngineContext, |
| 149 | __in const BOOTSTRAPPER_ACTION action | 149 | __in const BOOTSTRAPPER_ACTION action, |
| 150 | ); | 150 | __in const BOOTSTRAPPER_SCOPE plannedScope |
| 151 | ); | ||
| 151 | 152 | ||
| 152 | HRESULT ExternalEngineElevate( | 153 | HRESULT ExternalEngineElevate( |
| 153 | __in BAENGINE_CONTEXT* pEngineContext, | 154 | __in BAENGINE_CONTEXT* pEngineContext, |
diff --git a/src/burn/engine/logging.cpp b/src/burn/engine/logging.cpp index 52123499..47f52d27 100644 --- a/src/burn/engine/logging.cpp +++ b/src/burn/engine/logging.cpp | |||
| @@ -968,6 +968,42 @@ extern "C" LPCSTR LoggingInstallScopeToString( | |||
| 968 | return fPerMachine ? "PerMachine" : "PerUser"; | 968 | return fPerMachine ? "PerMachine" : "PerUser"; |
| 969 | } | 969 | } |
| 970 | 970 | ||
| 971 | extern "C" LPCSTR LoggingPackageScopeToString( | ||
| 972 | __in BOOTSTRAPPER_PACKAGE_SCOPE scope | ||
| 973 | ) | ||
| 974 | { | ||
| 975 | switch (scope) | ||
| 976 | { | ||
| 977 | case BOOTSTRAPPER_PACKAGE_SCOPE_PER_MACHINE: | ||
| 978 | return "PerMachine"; | ||
| 979 | case BOOTSTRAPPER_PACKAGE_SCOPE_PER_MACHINE_OR_PER_USER: | ||
| 980 | return "PerMachineOrUser"; | ||
| 981 | case BOOTSTRAPPER_PACKAGE_SCOPE_PER_USER_OR_PER_MACHINE: | ||
| 982 | return "PerUserOrMachine"; | ||
| 983 | case BOOTSTRAPPER_PACKAGE_SCOPE_PER_USER: | ||
| 984 | return "PerUser"; | ||
| 985 | default: | ||
| 986 | return "Invalid"; | ||
| 987 | } | ||
| 988 | } | ||
| 989 | |||
| 990 | extern "C" LPCSTR LoggingBundleScopeToString( | ||
| 991 | __in BOOTSTRAPPER_SCOPE scope | ||
| 992 | ) | ||
| 993 | { | ||
| 994 | switch (scope) | ||
| 995 | { | ||
| 996 | case BOOTSTRAPPER_SCOPE_DEFAULT: | ||
| 997 | return "Default"; | ||
| 998 | case BOOTSTRAPPER_SCOPE_PER_MACHINE: | ||
| 999 | return "PerMachine"; | ||
| 1000 | case BOOTSTRAPPER_SCOPE_PER_USER: | ||
| 1001 | return "PerUser"; | ||
| 1002 | default: | ||
| 1003 | return "Invalid"; | ||
| 1004 | } | ||
| 1005 | } | ||
| 1006 | |||
| 971 | 1007 | ||
| 972 | // internal function declarations | 1008 | // internal function declarations |
| 973 | 1009 | ||
diff --git a/src/burn/engine/logging.h b/src/burn/engine/logging.h index b28a53d4..76103732 100644 --- a/src/burn/engine/logging.h +++ b/src/burn/engine/logging.h | |||
| @@ -202,6 +202,13 @@ LPCSTR LoggingInstallScopeToString( | |||
| 202 | __in BOOL fPerMachine | 202 | __in BOOL fPerMachine |
| 203 | ); | 203 | ); |
| 204 | 204 | ||
| 205 | LPCSTR LoggingPackageScopeToString( | ||
| 206 | __in BOOTSTRAPPER_PACKAGE_SCOPE scope | ||
| 207 | ); | ||
| 208 | |||
| 209 | LPCSTR LoggingBundleScopeToString( | ||
| 210 | __in BOOTSTRAPPER_SCOPE scope | ||
| 211 | ); | ||
| 205 | 212 | ||
| 206 | #if defined(__cplusplus) | 213 | #if defined(__cplusplus) |
| 207 | } | 214 | } |
diff --git a/src/burn/engine/msiengine.cpp b/src/burn/engine/msiengine.cpp index a1379054..11bb8a0e 100644 --- a/src/burn/engine/msiengine.cpp +++ b/src/burn/engine/msiengine.cpp | |||
| @@ -454,7 +454,18 @@ extern "C" HRESULT MsiEngineDetectPackage( | |||
| 454 | 454 | ||
| 455 | // detect self by product code | 455 | // detect self by product code |
| 456 | // TODO: what to do about MSIINSTALLCONTEXT_USERMANAGED? | 456 | // TODO: what to do about MSIINSTALLCONTEXT_USERMANAGED? |
| 457 | hr = WiuGetProductInfoEx(pPackage->Msi.sczProductCode, NULL, pPackage->fPerMachine ? MSIINSTALLCONTEXT_MACHINE : MSIINSTALLCONTEXT_USERUNMANAGED, INSTALLPROPERTY_VERSIONSTRING, &sczInstalledVersion); | 457 | if (BOOTSTRAPPER_PACKAGE_SCOPE_PER_MACHINE_OR_PER_USER == pPackage->scope || BOOTSTRAPPER_PACKAGE_SCOPE_PER_USER_OR_PER_MACHINE == pPackage->scope) |
| 458 | { | ||
| 459 | hr = WiuGetProductInfoEx(pPackage->Msi.sczProductCode, NULL, MSIINSTALLCONTEXT_MACHINE, INSTALLPROPERTY_VERSIONSTRING, &sczInstalledVersion); | ||
| 460 | if (FAILED(hr)) | ||
| 461 | { | ||
| 462 | hr = WiuGetProductInfoEx(pPackage->Msi.sczProductCode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, INSTALLPROPERTY_VERSIONSTRING, &sczInstalledVersion); | ||
| 463 | } | ||
| 464 | } | ||
| 465 | else | ||
| 466 | { | ||
| 467 | hr = WiuGetProductInfoEx(pPackage->Msi.sczProductCode, NULL, pPackage->scope == BOOTSTRAPPER_PACKAGE_SCOPE_PER_MACHINE ? MSIINSTALLCONTEXT_MACHINE : MSIINSTALLCONTEXT_USERUNMANAGED, INSTALLPROPERTY_VERSIONSTRING, &sczInstalledVersion); | ||
| 468 | } | ||
| 458 | if (SUCCEEDED(hr)) | 469 | if (SUCCEEDED(hr)) |
| 459 | { | 470 | { |
| 460 | fDetectFeatures = TRUE; | 471 | fDetectFeatures = TRUE; |
| @@ -777,7 +788,18 @@ extern "C" HRESULT MsiEngineDetectCompatiblePackage( | |||
| 777 | ExitFunction(); | 788 | ExitFunction(); |
| 778 | } | 789 | } |
| 779 | 790 | ||
| 780 | hr = WiuGetProductInfoEx(wzCompatibleProductCode, NULL, pPackage->fPerMachine ? MSIINSTALLCONTEXT_MACHINE : MSIINSTALLCONTEXT_USERUNMANAGED, INSTALLPROPERTY_VERSIONSTRING, &sczVersion); | 791 | if (BOOTSTRAPPER_PACKAGE_SCOPE_PER_MACHINE_OR_PER_USER == pPackage->scope || BOOTSTRAPPER_PACKAGE_SCOPE_PER_USER_OR_PER_MACHINE == pPackage->scope) |
| 792 | { | ||
| 793 | hr = WiuGetProductInfoEx(wzCompatibleProductCode, NULL, MSIINSTALLCONTEXT_MACHINE, INSTALLPROPERTY_VERSIONSTRING, &sczVersion); | ||
| 794 | if (FAILED(hr)) | ||
| 795 | { | ||
| 796 | hr = WiuGetProductInfoEx(wzCompatibleProductCode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, INSTALLPROPERTY_VERSIONSTRING, &sczVersion); | ||
| 797 | } | ||
| 798 | } | ||
| 799 | else | ||
| 800 | { | ||
| 801 | hr = WiuGetProductInfoEx(wzCompatibleProductCode, NULL, pPackage->scope == BOOTSTRAPPER_PACKAGE_SCOPE_PER_MACHINE ? MSIINSTALLCONTEXT_MACHINE : MSIINSTALLCONTEXT_USERUNMANAGED, INSTALLPROPERTY_VERSIONSTRING, &sczVersion); | ||
| 802 | } | ||
| 781 | if (HRESULT_FROM_WIN32(ERROR_UNKNOWN_PRODUCT) == hr || HRESULT_FROM_WIN32(ERROR_UNKNOWN_PROPERTY) == hr || E_INVALIDARG == hr) | 803 | if (HRESULT_FROM_WIN32(ERROR_UNKNOWN_PRODUCT) == hr || HRESULT_FROM_WIN32(ERROR_UNKNOWN_PROPERTY) == hr || E_INVALIDARG == hr) |
| 782 | { | 804 | { |
| 783 | ExitFunction1(hr = S_OK); | 805 | ExitFunction1(hr = S_OK); |
| @@ -1336,10 +1358,10 @@ extern "C" HRESULT MsiEngineExecutePackage( | |||
| 1336 | hr = ConcatPatchProperty(pCache, pPackage, fRollback, &sczObfuscatedProperties); | 1358 | hr = ConcatPatchProperty(pCache, pPackage, fRollback, &sczObfuscatedProperties); |
| 1337 | ExitOnFailure(hr, "Failed to add patch properties to obfuscated argument string."); | 1359 | ExitOnFailure(hr, "Failed to add patch properties to obfuscated argument string."); |
| 1338 | 1360 | ||
| 1339 | hr = MsiEngineConcatBurnProperties(pExecuteAction->msiPackage.action, pExecuteAction->msiPackage.actionMsiProperty, pExecuteAction->msiPackage.fileVersioning, TRUE, 0 != pPackage->Msi.cFeatures, &sczProperties); | 1361 | hr = MsiEngineConcatBurnProperties(pExecuteAction->msiPackage.action, pExecuteAction->msiPackage.actionMsiProperty, pExecuteAction->msiPackage.fileVersioning, TRUE, 0 != pPackage->Msi.cFeatures, pExecuteAction->msiPackage.pPackage->scope, pExecuteAction->msiPackage.pPackage->fPerMachine, &sczProperties); |
| 1340 | ExitOnFailure(hr, "Failed to add action property to argument string."); | 1362 | ExitOnFailure(hr, "Failed to add action property to argument string."); |
| 1341 | 1363 | ||
| 1342 | hr = MsiEngineConcatBurnProperties(pExecuteAction->msiPackage.action, pExecuteAction->msiPackage.actionMsiProperty, pExecuteAction->msiPackage.fileVersioning, TRUE, 0 != pPackage->Msi.cFeatures, &sczObfuscatedProperties); | 1364 | hr = MsiEngineConcatBurnProperties(pExecuteAction->msiPackage.action, pExecuteAction->msiPackage.actionMsiProperty, pExecuteAction->msiPackage.fileVersioning, TRUE, 0 != pPackage->Msi.cFeatures, pPackage->scope, pPackage->fPerMachine, &sczObfuscatedProperties); |
| 1343 | ExitOnFailure(hr, "Failed to add action property to obfuscated argument string."); | 1365 | ExitOnFailure(hr, "Failed to add action property to obfuscated argument string."); |
| 1344 | 1366 | ||
| 1345 | LogId(REPORT_STANDARD, MSG_APPLYING_PACKAGE, LoggingRollbackOrExecute(fRollback), pPackage->sczId, LoggingActionStateToString(pExecuteAction->msiPackage.action), sczMsiPath, sczObfuscatedProperties ? sczObfuscatedProperties : L""); | 1367 | LogId(REPORT_STANDARD, MSG_APPLYING_PACKAGE, LoggingRollbackOrExecute(fRollback), pPackage->sczId, LoggingActionStateToString(pExecuteAction->msiPackage.action), sczMsiPath, sczObfuscatedProperties ? sczObfuscatedProperties : L""); |
| @@ -1449,7 +1471,7 @@ extern "C" HRESULT MsiEngineUninstallCompatiblePackage( | |||
| 1449 | ExitOnFailure(hr, "Failed to enable logging for compatible package: %ls to: %ls", pCompatibleEntry->sczId, pExecuteAction->uninstallMsiCompatiblePackage.sczLogPath); | 1471 | ExitOnFailure(hr, "Failed to enable logging for compatible package: %ls to: %ls", pCompatibleEntry->sczId, pExecuteAction->uninstallMsiCompatiblePackage.sczLogPath); |
| 1450 | } | 1472 | } |
| 1451 | 1473 | ||
| 1452 | hr = MsiEngineConcatBurnProperties(action, burnMsiProperty, fileVersioning, TRUE, FALSE, &sczProperties); | 1474 | hr = MsiEngineConcatBurnProperties(action, burnMsiProperty, fileVersioning, TRUE, FALSE, pParentPackage->scope, pParentPackage->fPerMachine, &sczProperties); |
| 1453 | ExitOnFailure(hr, "Failed to add action property to argument string."); | 1475 | ExitOnFailure(hr, "Failed to add action property to argument string."); |
| 1454 | 1476 | ||
| 1455 | LogId(REPORT_STANDARD, MSG_APPLYING_ORPHAN_COMPATIBLE_PACKAGE, LoggingRollbackOrExecute(fRollback), pCompatibleEntry->sczId, pParentPackage->sczId, LoggingActionStateToString(action), sczProperties ? sczProperties : L""); | 1477 | LogId(REPORT_STANDARD, MSG_APPLYING_ORPHAN_COMPATIBLE_PACKAGE, LoggingRollbackOrExecute(fRollback), pCompatibleEntry->sczId, pParentPackage->sczId, LoggingActionStateToString(action), sczProperties ? sczProperties : L""); |
| @@ -1491,6 +1513,8 @@ extern "C" HRESULT MsiEngineConcatBurnProperties( | |||
| 1491 | __in BOOTSTRAPPER_MSI_FILE_VERSIONING fileVersioning, | 1513 | __in BOOTSTRAPPER_MSI_FILE_VERSIONING fileVersioning, |
| 1492 | __in BOOL fMsiPackage, | 1514 | __in BOOL fMsiPackage, |
| 1493 | __in BOOL fFeatureSelectionEnabled, | 1515 | __in BOOL fFeatureSelectionEnabled, |
| 1516 | __in BOOTSTRAPPER_PACKAGE_SCOPE scope, | ||
| 1517 | __in BOOL fPlannedPerMachineScope, | ||
| 1494 | __deref_out_z LPWSTR* psczProperties | 1518 | __deref_out_z LPWSTR* psczProperties |
| 1495 | ) | 1519 | ) |
| 1496 | { | 1520 | { |
| @@ -1534,6 +1558,7 @@ extern "C" HRESULT MsiEngineConcatBurnProperties( | |||
| 1534 | break; | 1558 | break; |
| 1535 | } | 1559 | } |
| 1536 | 1560 | ||
| 1561 | // Append properties used by WixUI (and usable otherwise) to adjust internal UI behavior. | ||
| 1537 | switch (actionMsiProperty) | 1562 | switch (actionMsiProperty) |
| 1538 | { | 1563 | { |
| 1539 | case BURN_MSI_PROPERTY_INSTALL: | 1564 | case BURN_MSI_PROPERTY_INSTALL: |
| @@ -1581,6 +1606,20 @@ extern "C" HRESULT MsiEngineConcatBurnProperties( | |||
| 1581 | ExitOnFailure(hr, "Failed to add reinstall mode."); | 1606 | ExitOnFailure(hr, "Failed to add reinstall mode."); |
| 1582 | } | 1607 | } |
| 1583 | 1608 | ||
| 1609 | if (BOOTSTRAPPER_PACKAGE_SCOPE_PER_USER_OR_PER_MACHINE == scope || BOOTSTRAPPER_PACKAGE_SCOPE_PER_MACHINE_OR_PER_USER == scope) | ||
| 1610 | { | ||
| 1611 | if (fPlannedPerMachineScope) | ||
| 1612 | { | ||
| 1613 | hr = StrAllocConcatFormattedSecure(psczProperties, L" MSIINSTALLPERUSER=\"\""); | ||
| 1614 | ExitOnFailure(hr, "Failed to add per-machine scope properties."); | ||
| 1615 | } | ||
| 1616 | else | ||
| 1617 | { | ||
| 1618 | hr = StrAllocConcatFormattedSecure(psczProperties, L" MSIINSTALLPERUSER=\"1\""); | ||
| 1619 | ExitOnFailure(hr, "Failed to add per-user scope properties."); | ||
| 1620 | } | ||
| 1621 | } | ||
| 1622 | |||
| 1584 | hr = StrAllocConcatSecure(psczProperties, L" REBOOT=ReallySuppress", 0); | 1623 | hr = StrAllocConcatSecure(psczProperties, L" REBOOT=ReallySuppress", 0); |
| 1585 | ExitOnFailure(hr, "Failed to add reboot suppression property."); | 1624 | ExitOnFailure(hr, "Failed to add reboot suppression property."); |
| 1586 | 1625 | ||
diff --git a/src/burn/engine/msiengine.h b/src/burn/engine/msiengine.h index 862c4f6a..d4660dc8 100644 --- a/src/burn/engine/msiengine.h +++ b/src/burn/engine/msiengine.h | |||
| @@ -93,6 +93,8 @@ HRESULT MsiEngineConcatBurnProperties( | |||
| 93 | __in BOOTSTRAPPER_MSI_FILE_VERSIONING fileVersioning, | 93 | __in BOOTSTRAPPER_MSI_FILE_VERSIONING fileVersioning, |
| 94 | __in BOOL fMsiPackage, | 94 | __in BOOL fMsiPackage, |
| 95 | __in BOOL fFeatureSelectionEnabled, | 95 | __in BOOL fFeatureSelectionEnabled, |
| 96 | __in BOOTSTRAPPER_PACKAGE_SCOPE scope, | ||
| 97 | __in BOOL fPlannedPerMachineScope, | ||
| 96 | __deref_out_z LPWSTR* psczProperties | 98 | __deref_out_z LPWSTR* psczProperties |
| 97 | ); | 99 | ); |
| 98 | HRESULT MsiEngineConcatPackageProperties( | 100 | HRESULT MsiEngineConcatPackageProperties( |
diff --git a/src/burn/engine/mspengine.cpp b/src/burn/engine/mspengine.cpp index e8ef7fcb..18be3cc6 100644 --- a/src/burn/engine/mspengine.cpp +++ b/src/burn/engine/mspengine.cpp | |||
| @@ -676,10 +676,10 @@ extern "C" HRESULT MspEngineExecutePackage( | |||
| 676 | } | 676 | } |
| 677 | 677 | ||
| 678 | // Always add Burn properties last. | 678 | // Always add Burn properties last. |
| 679 | hr = MsiEngineConcatBurnProperties(pExecuteAction->mspTarget.action, pExecuteAction->mspTarget.actionMsiProperty, pExecuteAction->mspTarget.fileVersioning, FALSE, FALSE, &sczProperties); | 679 | hr = MsiEngineConcatBurnProperties(pExecuteAction->mspTarget.action, pExecuteAction->mspTarget.actionMsiProperty, pExecuteAction->mspTarget.fileVersioning, FALSE, FALSE, pExecuteAction->mspTarget.pPackage->scope, pExecuteAction->mspTarget.pPackage->fPerMachine, &sczProperties); |
| 680 | ExitOnFailure(hr, "Failed to add action property to argument string."); | 680 | ExitOnFailure(hr, "Failed to add action property to argument string."); |
| 681 | 681 | ||
| 682 | hr = MsiEngineConcatBurnProperties(pExecuteAction->mspTarget.action, pExecuteAction->mspTarget.actionMsiProperty, pExecuteAction->mspTarget.fileVersioning, FALSE, FALSE, &sczObfuscatedProperties); | 682 | hr = MsiEngineConcatBurnProperties(pExecuteAction->mspTarget.action, pExecuteAction->mspTarget.actionMsiProperty, pExecuteAction->mspTarget.fileVersioning, FALSE, FALSE, pExecuteAction->mspTarget.pPackage->scope, pExecuteAction->mspTarget.pPackage->fPerMachine, &sczObfuscatedProperties); |
| 683 | ExitOnFailure(hr, "Failed to add action property to obfuscated argument string."); | 683 | ExitOnFailure(hr, "Failed to add action property to obfuscated argument string."); |
| 684 | 684 | ||
| 685 | LogId(REPORT_STANDARD, MSG_APPLYING_PATCH_PACKAGE, pExecuteAction->mspTarget.pPackage->sczId, LoggingActionStateToString(pExecuteAction->mspTarget.action), sczPatches, sczObfuscatedProperties, pExecuteAction->mspTarget.sczTargetProductCode); | 685 | LogId(REPORT_STANDARD, MSG_APPLYING_PATCH_PACKAGE, pExecuteAction->mspTarget.pPackage->sczId, LoggingActionStateToString(pExecuteAction->mspTarget.action), sczPatches, sczObfuscatedProperties, pExecuteAction->mspTarget.sczTargetProductCode); |
diff --git a/src/burn/engine/package.cpp b/src/burn/engine/package.cpp index 3bf676ba..61b73dc6 100644 --- a/src/burn/engine/package.cpp +++ b/src/burn/engine/package.cpp | |||
| @@ -154,9 +154,12 @@ extern "C" HRESULT PackagesParseFromXml( | |||
| 154 | hr = XmlGetAttributeUInt64(pixnNode, L"InstallSize", &pPackage->qwInstallSize); | 154 | hr = XmlGetAttributeUInt64(pixnNode, L"InstallSize", &pPackage->qwInstallSize); |
| 155 | ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @InstallSize."); | 155 | ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @InstallSize."); |
| 156 | 156 | ||
| 157 | // @PerMachine | 157 | // @Scope |
| 158 | hr = XmlGetYesNoAttribute(pixnNode, L"PerMachine", &pPackage->fPerMachine); | 158 | hr = PackageParseScopeFromXml(pixnNode, &pPackage->scope); |
| 159 | ExitOnRequiredXmlQueryFailure(hr, "Failed to get @PerMachine."); | 159 | ExitOnRequiredXmlQueryFailure(hr, "Failed to get @Scope."); |
| 160 | |||
| 161 | // Shortcut for static per-machine or per-user packages. | ||
| 162 | pPackage->fPerMachine = BOOTSTRAPPER_PACKAGE_SCOPE_PER_MACHINE == pPackage->scope; | ||
| 160 | 163 | ||
| 161 | // @Permanent | 164 | // @Permanent |
| 162 | hr = XmlGetYesNoAttribute(pixnNode, L"Permanent", &pPackage->fPermanent); | 165 | hr = XmlGetYesNoAttribute(pixnNode, L"Permanent", &pPackage->fPermanent); |
| @@ -593,6 +596,45 @@ LExit: | |||
| 593 | return hr; | 596 | return hr; |
| 594 | } | 597 | } |
| 595 | 598 | ||
| 599 | extern "C" HRESULT PackageParseScopeFromXml( | ||
| 600 | __in IXMLDOMNode* pixn, | ||
| 601 | __in BOOTSTRAPPER_PACKAGE_SCOPE* pScope | ||
| 602 | ) | ||
| 603 | { | ||
| 604 | HRESULT hr = S_OK; | ||
| 605 | LPWSTR scz = NULL; | ||
| 606 | |||
| 607 | hr = XmlGetAttributeEx(pixn, L"Scope", &scz); | ||
| 608 | ExitOnRequiredXmlQueryFailure(hr, "Failed to get @Scope."); | ||
| 609 | |||
| 610 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, scz, -1, L"perMachine", -1)) | ||
| 611 | { | ||
| 612 | *pScope = BOOTSTRAPPER_PACKAGE_SCOPE_PER_MACHINE; | ||
| 613 | } | ||
| 614 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, scz, -1, L"perUser", -1)) | ||
| 615 | { | ||
| 616 | *pScope = BOOTSTRAPPER_PACKAGE_SCOPE_PER_USER; | ||
| 617 | } | ||
| 618 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, scz, -1, L"perUserOrMachine", -1)) | ||
| 619 | { | ||
| 620 | *pScope = BOOTSTRAPPER_PACKAGE_SCOPE_PER_USER_OR_PER_MACHINE; | ||
| 621 | } | ||
| 622 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, scz, -1, L"perMachineOrUser", -1)) | ||
| 623 | { | ||
| 624 | *pScope = BOOTSTRAPPER_PACKAGE_SCOPE_PER_MACHINE_OR_PER_USER; | ||
| 625 | } | ||
| 626 | else | ||
| 627 | { | ||
| 628 | hr = E_UNEXPECTED; | ||
| 629 | ExitOnRootFailure(hr, "Invalid scope: %ls", scz); | ||
| 630 | } | ||
| 631 | |||
| 632 | LExit: | ||
| 633 | ReleaseStr(scz); | ||
| 634 | |||
| 635 | return hr; | ||
| 636 | } | ||
| 637 | |||
| 596 | 638 | ||
| 597 | // internal function declarations | 639 | // internal function declarations |
| 598 | 640 | ||
diff --git a/src/burn/engine/package.h b/src/burn/engine/package.h index d596d7c0..5397e9cc 100644 --- a/src/burn/engine/package.h +++ b/src/burn/engine/package.h | |||
| @@ -268,7 +268,8 @@ typedef struct _BURN_PACKAGE | |||
| 268 | 268 | ||
| 269 | LPWSTR sczInstallCondition; | 269 | LPWSTR sczInstallCondition; |
| 270 | LPWSTR sczRepairCondition; | 270 | LPWSTR sczRepairCondition; |
| 271 | BOOL fPerMachine; | 271 | BOOTSTRAPPER_PACKAGE_SCOPE scope; |
| 272 | BOOL fPerMachine; // only valid after Plan (for PUOM/PMOU packages). | ||
| 272 | BOOL fPermanent; | 273 | BOOL fPermanent; |
| 273 | BOOL fVital; | 274 | BOOL fVital; |
| 274 | BOOL fCanAffectRegistration; | 275 | BOOL fCanAffectRegistration; |
| @@ -483,6 +484,10 @@ HRESULT PackageFindRollbackBoundaryById( | |||
| 483 | __in_z LPCWSTR wzId, | 484 | __in_z LPCWSTR wzId, |
| 484 | __out BURN_ROLLBACK_BOUNDARY** ppRollbackBoundary | 485 | __out BURN_ROLLBACK_BOUNDARY** ppRollbackBoundary |
| 485 | ); | 486 | ); |
| 487 | HRESULT PackageParseScopeFromXml( | ||
| 488 | __in IXMLDOMNode* pixn, | ||
| 489 | __in BOOTSTRAPPER_PACKAGE_SCOPE* pScope | ||
| 490 | ); | ||
| 486 | 491 | ||
| 487 | 492 | ||
| 488 | #if defined(__cplusplus) | 493 | #if defined(__cplusplus) |
diff --git a/src/burn/engine/plan.cpp b/src/burn/engine/plan.cpp index edc09033..6c46269b 100644 --- a/src/burn/engine/plan.cpp +++ b/src/burn/engine/plan.cpp | |||
| @@ -278,7 +278,7 @@ extern "C" void PlanReset( | |||
| 278 | } | 278 | } |
| 279 | } | 279 | } |
| 280 | 280 | ||
| 281 | PlanSetVariables(BOOTSTRAPPER_ACTION_UNKNOWN, pVariables); | 281 | PlanSetVariables(BOOTSTRAPPER_ACTION_UNKNOWN, BOOTSTRAPPER_PACKAGE_SCOPE_INVALID, BOOTSTRAPPER_SCOPE_DEFAULT, pVariables); |
| 282 | } | 282 | } |
| 283 | 283 | ||
| 284 | extern "C" void PlanUninitializeExecuteAction( | 284 | extern "C" void PlanUninitializeExecuteAction( |
| @@ -332,6 +332,8 @@ extern "C" void PlanUninitializeExecuteAction( | |||
| 332 | 332 | ||
| 333 | extern "C" HRESULT PlanSetVariables( | 333 | extern "C" HRESULT PlanSetVariables( |
| 334 | __in BOOTSTRAPPER_ACTION action, | 334 | __in BOOTSTRAPPER_ACTION action, |
| 335 | __in BOOTSTRAPPER_PACKAGE_SCOPE authoredScope, | ||
| 336 | __in BOOTSTRAPPER_SCOPE plannedScope, | ||
| 335 | __in BURN_VARIABLES* pVariables | 337 | __in BURN_VARIABLES* pVariables |
| 336 | ) | 338 | ) |
| 337 | { | 339 | { |
| @@ -340,6 +342,12 @@ extern "C" HRESULT PlanSetVariables( | |||
| 340 | hr = VariableSetNumeric(pVariables, BURN_BUNDLE_ACTION, action, TRUE); | 342 | hr = VariableSetNumeric(pVariables, BURN_BUNDLE_ACTION, action, TRUE); |
| 341 | ExitOnFailure(hr, "Failed to set the bundle action built-in variable."); | 343 | ExitOnFailure(hr, "Failed to set the bundle action built-in variable."); |
| 342 | 344 | ||
| 345 | hr = VariableSetNumeric(pVariables, BURN_BUNDLE_SCOPE, authoredScope, TRUE); | ||
| 346 | ExitOnFailure(hr, "Failed to set the bundle authored scope built-in variable."); | ||
| 347 | |||
| 348 | hr = VariableSetNumeric(pVariables, BURN_BUNDLE_PLANNED_SCOPE, plannedScope, TRUE); | ||
| 349 | ExitOnFailure(hr, "Failed to set the bundle planned scope built-in variable."); | ||
| 350 | |||
| 343 | LExit: | 351 | LExit: |
| 344 | return hr; | 352 | return hr; |
| 345 | } | 353 | } |
| @@ -812,6 +820,66 @@ LExit: | |||
| 812 | return hr; | 820 | return hr; |
| 813 | } | 821 | } |
| 814 | 822 | ||
| 823 | extern "C" HRESULT PlanPackagesAndBundleScope( | ||
| 824 | __in BURN_PACKAGE* rgPackages, | ||
| 825 | __in DWORD cPackages, | ||
| 826 | __in BOOTSTRAPPER_SCOPE scope, | ||
| 827 | __in BOOTSTRAPPER_PACKAGE_SCOPE authoredScope, | ||
| 828 | __in BOOTSTRAPPER_SCOPE commandLineScope, | ||
| 829 | __out BOOTSTRAPPER_SCOPE* pResultingScope, | ||
| 830 | __out BOOL* pfRegistrationPerMachine | ||
| 831 | ) | ||
| 832 | { | ||
| 833 | HRESULT hr = S_OK; | ||
| 834 | BOOL fRegistrationPerMachine = TRUE; | ||
| 835 | |||
| 836 | // If a scope was specified on the command line and the BA didn't set a scope, | ||
| 837 | // let the command-line switch override. | ||
| 838 | if (BOOTSTRAPPER_SCOPE_DEFAULT != commandLineScope) | ||
| 839 | { | ||
| 840 | if (BOOTSTRAPPER_PACKAGE_SCOPE_PER_MACHINE_OR_PER_USER == authoredScope || BOOTSTRAPPER_PACKAGE_SCOPE_PER_USER_OR_PER_MACHINE == authoredScope) | ||
| 841 | { | ||
| 842 | if (BOOTSTRAPPER_SCOPE_DEFAULT == scope) | ||
| 843 | { | ||
| 844 | scope = commandLineScope; | ||
| 845 | } | ||
| 846 | else | ||
| 847 | { | ||
| 848 | LogId(REPORT_STANDARD, MSG_SCOPE_IGNORED_BA_SCOPE); | ||
| 849 | } | ||
| 850 | } | ||
| 851 | else | ||
| 852 | { | ||
| 853 | LogId(REPORT_STANDARD, MSG_SCOPE_IGNORED_UNCONFIGURABLE); | ||
| 854 | } | ||
| 855 | } | ||
| 856 | |||
| 857 | for (DWORD i = 0; i < cPackages; ++i) | ||
| 858 | { | ||
| 859 | BURN_PACKAGE* pPackage = rgPackages + i; | ||
| 860 | |||
| 861 | pPackage->fPerMachine = | ||
| 862 | (BOOTSTRAPPER_PACKAGE_SCOPE_PER_MACHINE == pPackage->scope) | ||
| 863 | || (BOOTSTRAPPER_PACKAGE_SCOPE_PER_MACHINE_OR_PER_USER == pPackage->scope && | ||
| 864 | (BOOTSTRAPPER_SCOPE_DEFAULT == scope || BOOTSTRAPPER_SCOPE_PER_MACHINE == scope)) | ||
| 865 | || (BOOTSTRAPPER_PACKAGE_SCOPE_PER_USER_OR_PER_MACHINE == pPackage->scope && | ||
| 866 | BOOTSTRAPPER_SCOPE_PER_MACHINE == scope); | ||
| 867 | |||
| 868 | // Any per-user package makes the registration per-user as well. | ||
| 869 | if (!pPackage->fPerMachine) | ||
| 870 | { | ||
| 871 | fRegistrationPerMachine = FALSE; | ||
| 872 | } | ||
| 873 | } | ||
| 874 | |||
| 875 | *pResultingScope = scope; | ||
| 876 | *pfRegistrationPerMachine = fRegistrationPerMachine; | ||
| 877 | |||
| 878 | //LExit: | ||
| 879 | return hr; | ||
| 880 | } | ||
| 881 | |||
| 882 | |||
| 815 | static HRESULT PlanPackagesHelper( | 883 | static HRESULT PlanPackagesHelper( |
| 816 | __in BURN_PACKAGE* rgPackages, | 884 | __in BURN_PACKAGE* rgPackages, |
| 817 | __in DWORD cPackages, | 885 | __in DWORD cPackages, |
| @@ -2971,7 +3039,7 @@ static void ExecuteActionLog( | |||
| 2971 | break; | 3039 | break; |
| 2972 | 3040 | ||
| 2973 | case BURN_EXECUTE_ACTION_TYPE_MSI_PACKAGE: | 3041 | case BURN_EXECUTE_ACTION_TYPE_MSI_PACKAGE: |
| 2974 | LogStringLine(PlanDumpLevel, "%ls action[%u]: MSI_PACKAGE package id: %ls, action: %hs, action msi property: %ls, ui level: %u, disable externaluihandler: %hs, file versioning: %hs, log path: %ls, logging attrib: %u", wzBase, iAction, pAction->msiPackage.pPackage->sczId, LoggingActionStateToString(pAction->msiPackage.action), LoggingBurnMsiPropertyToString(pAction->msiPackage.actionMsiProperty), pAction->msiPackage.uiLevel, LoggingBoolToString(pAction->msiPackage.fDisableExternalUiHandler), LoggingMsiFileVersioningToString(pAction->msiPackage.fileVersioning), pAction->msiPackage.sczLogPath, pAction->msiPackage.dwLoggingAttributes); | 3042 | LogStringLine(PlanDumpLevel, "%ls action[%u]: MSI_PACKAGE package id: %ls, scope: %hs, action: %hs, action msi property: %ls, ui level: %u, disable externaluihandler: %hs, file versioning: %hs, log path: %ls, logging attrib: %u", wzBase, iAction, pAction->msiPackage.pPackage->sczId, LoggingPackageScopeToString(pAction->msiPackage.pPackage->scope), LoggingActionStateToString(pAction->msiPackage.action), LoggingBurnMsiPropertyToString(pAction->msiPackage.actionMsiProperty), pAction->msiPackage.uiLevel, LoggingBoolToString(pAction->msiPackage.fDisableExternalUiHandler), LoggingMsiFileVersioningToString(pAction->msiPackage.fileVersioning), pAction->msiPackage.sczLogPath, pAction->msiPackage.dwLoggingAttributes); |
| 2975 | for (DWORD j = 0; j < pAction->msiPackage.pPackage->Msi.cSlipstreamMspPackages; ++j) | 3043 | for (DWORD j = 0; j < pAction->msiPackage.pPackage->Msi.cSlipstreamMspPackages; ++j) |
| 2976 | { | 3044 | { |
| 2977 | const BURN_SLIPSTREAM_MSP* pSlipstreamMsp = pAction->msiPackage.pPackage->Msi.rgSlipstreamMsps + j; | 3045 | const BURN_SLIPSTREAM_MSP* pSlipstreamMsp = pAction->msiPackage.pPackage->Msi.rgSlipstreamMsps + j; |
| @@ -3083,6 +3151,7 @@ extern "C" void PlanDump( | |||
| 3083 | LogStringLine(PlanDumpLevel, " bundle code: %ls", pPlan->wzBundleCode); | 3151 | LogStringLine(PlanDumpLevel, " bundle code: %ls", pPlan->wzBundleCode); |
| 3084 | LogStringLine(PlanDumpLevel, " bundle provider key: %ls", pPlan->wzBundleProviderKey); | 3152 | LogStringLine(PlanDumpLevel, " bundle provider key: %ls", pPlan->wzBundleProviderKey); |
| 3085 | LogStringLine(PlanDumpLevel, " use-forward-compatible: %hs", LoggingTrueFalseToString(pPlan->fEnabledForwardCompatibleBundle)); | 3153 | LogStringLine(PlanDumpLevel, " use-forward-compatible: %hs", LoggingTrueFalseToString(pPlan->fEnabledForwardCompatibleBundle)); |
| 3154 | LogStringLine(PlanDumpLevel, " planned scope: %hs", LoggingBundleScopeToString(pPlan->plannedScope)); | ||
| 3086 | LogStringLine(PlanDumpLevel, " per-machine: %hs", LoggingTrueFalseToString(pPlan->fPerMachine)); | 3155 | LogStringLine(PlanDumpLevel, " per-machine: %hs", LoggingTrueFalseToString(pPlan->fPerMachine)); |
| 3087 | LogStringLine(PlanDumpLevel, " can affect machine state: %hs", LoggingTrueFalseToString(pPlan->fCanAffectMachineState)); | 3156 | LogStringLine(PlanDumpLevel, " can affect machine state: %hs", LoggingTrueFalseToString(pPlan->fCanAffectMachineState)); |
| 3088 | LogStringLine(PlanDumpLevel, " disable-rollback: %hs", LoggingTrueFalseToString(pPlan->fDisableRollback)); | 3157 | LogStringLine(PlanDumpLevel, " disable-rollback: %hs", LoggingTrueFalseToString(pPlan->fDisableRollback)); |
diff --git a/src/burn/engine/plan.h b/src/burn/engine/plan.h index 03b1423d..a20d7c76 100644 --- a/src/burn/engine/plan.h +++ b/src/burn/engine/plan.h | |||
| @@ -249,6 +249,7 @@ typedef struct _BURN_CLEAN_ACTION | |||
| 249 | typedef struct _BURN_PLAN | 249 | typedef struct _BURN_PLAN |
| 250 | { | 250 | { |
| 251 | BOOTSTRAPPER_ACTION action; | 251 | BOOTSTRAPPER_ACTION action; |
| 252 | BOOTSTRAPPER_SCOPE plannedScope; | ||
| 252 | BURN_CACHE* pCache; | 253 | BURN_CACHE* pCache; |
| 253 | BOOTSTRAPPER_COMMAND* pCommand; | 254 | BOOTSTRAPPER_COMMAND* pCommand; |
| 254 | BURN_ENGINE_COMMAND* pInternalCommand; | 255 | BURN_ENGINE_COMMAND* pInternalCommand; |
| @@ -328,6 +329,8 @@ void PlanUninitializeExecuteAction( | |||
| 328 | ); | 329 | ); |
| 329 | HRESULT PlanSetVariables( | 330 | HRESULT PlanSetVariables( |
| 330 | __in BOOTSTRAPPER_ACTION action, | 331 | __in BOOTSTRAPPER_ACTION action, |
| 332 | __in BOOTSTRAPPER_PACKAGE_SCOPE authoredScope, | ||
| 333 | __in BOOTSTRAPPER_SCOPE plannedScope, | ||
| 331 | __in BURN_VARIABLES* pVariables | 334 | __in BURN_VARIABLES* pVariables |
| 332 | ); | 335 | ); |
| 333 | HRESULT PlanDefaultRelatedBundlePlanType( | 336 | HRESULT PlanDefaultRelatedBundlePlanType( |
| @@ -479,6 +482,15 @@ HRESULT PlanSetResumeCommand( | |||
| 479 | void PlanDump( | 482 | void PlanDump( |
| 480 | __in BURN_PLAN* pPlan | 483 | __in BURN_PLAN* pPlan |
| 481 | ); | 484 | ); |
| 485 | HRESULT PlanPackagesAndBundleScope( | ||
| 486 | __in BURN_PACKAGE* rgPackages, | ||
| 487 | __in DWORD cPackages, | ||
| 488 | __in BOOTSTRAPPER_SCOPE scope, | ||
| 489 | __in BOOTSTRAPPER_PACKAGE_SCOPE authoredScope, | ||
| 490 | __in BOOTSTRAPPER_SCOPE commandLineScope, | ||
| 491 | __out BOOTSTRAPPER_SCOPE* pResultingScope, | ||
| 492 | __out BOOL* pfPerMachine | ||
| 493 | ); | ||
| 482 | 494 | ||
| 483 | #if defined(__cplusplus) | 495 | #if defined(__cplusplus) |
| 484 | } | 496 | } |
diff --git a/src/burn/engine/registration.cpp b/src/burn/engine/registration.cpp index 9733e92c..fa1b024a 100644 --- a/src/burn/engine/registration.cpp +++ b/src/burn/engine/registration.cpp | |||
| @@ -39,10 +39,6 @@ static HRESULT ParseSoftwareTagsFromXml( | |||
| 39 | __out BURN_SOFTWARE_TAG** prgSoftwareTags, | 39 | __out BURN_SOFTWARE_TAG** prgSoftwareTags, |
| 40 | __out DWORD* pcSoftwareTags | 40 | __out DWORD* pcSoftwareTags |
| 41 | ); | 41 | ); |
| 42 | static HRESULT SetPaths( | ||
| 43 | __in BURN_REGISTRATION* pRegistration, | ||
| 44 | __in BURN_CACHE* pCache | ||
| 45 | ); | ||
| 46 | static HRESULT GetBundleManufacturer( | 42 | static HRESULT GetBundleManufacturer( |
| 47 | __in BURN_REGISTRATION* pRegistration, | 43 | __in BURN_REGISTRATION* pRegistration, |
| 48 | __in BURN_VARIABLES* pVariables, | 44 | __in BURN_VARIABLES* pVariables, |
| @@ -108,6 +104,15 @@ static HRESULT UpdateEstimatedSize( | |||
| 108 | ); | 104 | ); |
| 109 | static BOOL IsWuRebootPending(); | 105 | static BOOL IsWuRebootPending(); |
| 110 | static BOOL IsRegistryRebootPending(); | 106 | static BOOL IsRegistryRebootPending(); |
| 107 | static HRESULT RegistrationDetectResumeTypeByHive( | ||
| 108 | __in HKEY hkRegistrationRoot, | ||
| 109 | __in BURN_REGISTRATION* pRegistration, | ||
| 110 | __out BOOTSTRAPPER_RESUME_TYPE* pResumeType | ||
| 111 | ); | ||
| 112 | static HRESULT DetectInstalled( | ||
| 113 | __in BURN_REGISTRATION* pRegistration, | ||
| 114 | __in HKEY hkRoot | ||
| 115 | ); | ||
| 111 | 116 | ||
| 112 | // function definitions | 117 | // function definitions |
| 113 | 118 | ||
| @@ -163,9 +168,9 @@ extern "C" HRESULT RegistrationParseFromXml( | |||
| 163 | hr = XmlGetAttributeEx(pixnRegistrationNode, L"ExecutableName", &pRegistration->sczExecutableName); | 168 | hr = XmlGetAttributeEx(pixnRegistrationNode, L"ExecutableName", &pRegistration->sczExecutableName); |
| 164 | ExitOnRequiredXmlQueryFailure(hr, "Failed to get @ExecutableName."); | 169 | ExitOnRequiredXmlQueryFailure(hr, "Failed to get @ExecutableName."); |
| 165 | 170 | ||
| 166 | // @PerMachine | 171 | // @Scope |
| 167 | hr = XmlGetYesNoAttribute(pixnRegistrationNode, L"PerMachine", &pRegistration->fPerMachine); | 172 | hr = PackageParseScopeFromXml(pixnRegistrationNode, &pRegistration->scope); |
| 168 | ExitOnRequiredXmlQueryFailure(hr, "Failed to get @PerMachine."); | 173 | ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @Scope."); |
| 169 | 174 | ||
| 170 | // select ARP node | 175 | // select ARP node |
| 171 | hr = XmlSelectSingleNode(pixnRegistrationNode, L"Arp", &pixnArpNode); | 176 | hr = XmlSelectSingleNode(pixnRegistrationNode, L"Arp", &pixnArpNode); |
| @@ -285,8 +290,18 @@ extern "C" HRESULT RegistrationParseFromXml( | |||
| 285 | ExitOnRequiredXmlQueryFailure(hr, "Failed to get @Classification."); | 290 | ExitOnRequiredXmlQueryFailure(hr, "Failed to get @Classification."); |
| 286 | } | 291 | } |
| 287 | 292 | ||
| 288 | hr = SetPaths(pRegistration, pCache); | 293 | // Handle the easy case of build-time bundle scope early. |
| 289 | ExitOnFailure(hr, "Failed to set registration paths."); | 294 | if (BOOTSTRAPPER_PACKAGE_SCOPE_PER_MACHINE == pRegistration->scope || BOOTSTRAPPER_PACKAGE_SCOPE_PER_USER == pRegistration->scope) |
| 295 | { | ||
| 296 | pRegistration->fPerMachine = BOOTSTRAPPER_PACKAGE_SCOPE_PER_MACHINE == pRegistration->scope; | ||
| 297 | |||
| 298 | hr = RegistrationSetPaths(pRegistration, pCache); | ||
| 299 | ExitOnFailure(hr, "Failed to set registration paths for fixed scope."); | ||
| 300 | } | ||
| 301 | else | ||
| 302 | { | ||
| 303 | pRegistration->hkRoot = reinterpret_cast<HKEY>(0ull); | ||
| 304 | } | ||
| 290 | 305 | ||
| 291 | LExit: | 306 | LExit: |
| 292 | ReleaseObject(pixnRegistrationNode); | 307 | ReleaseObject(pixnRegistrationNode); |
| @@ -452,31 +467,28 @@ LExit: | |||
| 452 | 467 | ||
| 453 | extern "C" HRESULT RegistrationDetectInstalled( | 468 | extern "C" HRESULT RegistrationDetectInstalled( |
| 454 | __in BURN_REGISTRATION* pRegistration | 469 | __in BURN_REGISTRATION* pRegistration |
| 455 | ) | 470 | ) |
| 456 | { | 471 | { |
| 457 | HRESULT hr = S_OK; | 472 | HRESULT hr = S_OK; |
| 458 | HKEY hkRegistration = NULL; | ||
| 459 | DWORD dwInstalled = 0; | ||
| 460 | 473 | ||
| 461 | pRegistration->fCached = FileExistsEx(pRegistration->sczCacheExecutablePath, NULL); | 474 | if (pRegistration->hkRoot) |
| 462 | pRegistration->detectedRegistrationType = BOOTSTRAPPER_REGISTRATION_TYPE_NONE; | ||
| 463 | |||
| 464 | // open registration key | ||
| 465 | hr = RegOpen(pRegistration->hkRoot, pRegistration->sczRegistrationKey, KEY_QUERY_VALUE, &hkRegistration); | ||
| 466 | if (SUCCEEDED(hr)) | ||
| 467 | { | 475 | { |
| 468 | hr = RegReadNumber(hkRegistration, REGISTRY_BUNDLE_INSTALLED, &dwInstalled); | 476 | hr = DetectInstalled(pRegistration, pRegistration->hkRoot); |
| 469 | |||
| 470 | pRegistration->detectedRegistrationType = (1 == dwInstalled) ? BOOTSTRAPPER_REGISTRATION_TYPE_FULL : BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS; | ||
| 471 | } | 477 | } |
| 472 | 478 | else | |
| 473 | // Not finding the key or value is okay. | ||
| 474 | if (E_FILENOTFOUND == hr || E_PATHNOTFOUND == hr) | ||
| 475 | { | 479 | { |
| 476 | hr = S_OK; | 480 | // For PUOM/PMOU bundles, check per-machine then fall back to per-user. |
| 481 | hr = DetectInstalled(pRegistration, HKEY_LOCAL_MACHINE); | ||
| 482 | ExitOnFailure(hr, "Failed to detect HKEY_LOCAL_MACHINE bundle registration install state."); | ||
| 483 | |||
| 484 | if (BOOTSTRAPPER_REGISTRATION_TYPE_NONE == pRegistration->detectedRegistrationType) | ||
| 485 | { | ||
| 486 | hr = DetectInstalled(pRegistration, HKEY_CURRENT_USER); | ||
| 487 | ExitOnFailure(hr, "Failed to detect HKEY_CURRENT_USER bundle registration install state."); | ||
| 488 | } | ||
| 477 | } | 489 | } |
| 478 | 490 | ||
| 479 | ReleaseRegKey(hkRegistration); | 491 | LExit: |
| 480 | return hr; | 492 | return hr; |
| 481 | } | 493 | } |
| 482 | 494 | ||
| @@ -488,63 +500,26 @@ extern "C" HRESULT RegistrationDetectInstalled( | |||
| 488 | extern "C" HRESULT RegistrationDetectResumeType( | 500 | extern "C" HRESULT RegistrationDetectResumeType( |
| 489 | __in BURN_REGISTRATION* pRegistration, | 501 | __in BURN_REGISTRATION* pRegistration, |
| 490 | __out BOOTSTRAPPER_RESUME_TYPE* pResumeType | 502 | __out BOOTSTRAPPER_RESUME_TYPE* pResumeType |
| 491 | ) | 503 | ) |
| 492 | { | 504 | { |
| 493 | HRESULT hr = S_OK; | 505 | HRESULT hr = S_OK; |
| 494 | HKEY hkRegistration = NULL; | ||
| 495 | BOOL fExists = FALSE; | ||
| 496 | DWORD dwResume = 0; | ||
| 497 | 506 | ||
| 498 | // open registration key | 507 | if (pRegistration->hkRoot) |
| 499 | hr = RegOpen(pRegistration->hkRoot, pRegistration->sczRegistrationKey, KEY_QUERY_VALUE, &hkRegistration); | ||
| 500 | ExitOnPathFailure(hr, fExists, "Failed to open registration key."); | ||
| 501 | |||
| 502 | if (!fExists) | ||
| 503 | { | 508 | { |
| 504 | *pResumeType = BOOTSTRAPPER_RESUME_TYPE_NONE; | 509 | hr = RegistrationDetectResumeTypeByHive(pRegistration->hkRoot, pRegistration, pResumeType); |
| 505 | ExitFunction(); | ||
| 506 | } | 510 | } |
| 507 | 511 | else | |
| 508 | // read Resume value | ||
| 509 | hr = RegReadNumber(hkRegistration, L"Resume", &dwResume); | ||
| 510 | ExitOnPathFailure(hr, fExists, "Failed to read Resume value."); | ||
| 511 | |||
| 512 | if (!fExists) | ||
| 513 | { | ||
| 514 | *pResumeType = BOOTSTRAPPER_RESUME_TYPE_INVALID; | ||
| 515 | ExitFunction(); | ||
| 516 | } | ||
| 517 | |||
| 518 | switch (dwResume) | ||
| 519 | { | 512 | { |
| 520 | case BURN_RESUME_MODE_ACTIVE: | 513 | hr = RegistrationDetectResumeTypeByHive(HKEY_LOCAL_MACHINE, pRegistration, pResumeType); |
| 521 | // a previous run was interrupted | ||
| 522 | *pResumeType = BOOTSTRAPPER_RESUME_TYPE_INTERRUPTED; | ||
| 523 | break; | ||
| 524 | |||
| 525 | case BURN_RESUME_MODE_SUSPEND: | ||
| 526 | *pResumeType = BOOTSTRAPPER_RESUME_TYPE_SUSPEND; | ||
| 527 | break; | ||
| 528 | |||
| 529 | case BURN_RESUME_MODE_ARP: | ||
| 530 | *pResumeType = BOOTSTRAPPER_RESUME_TYPE_ARP; | ||
| 531 | break; | ||
| 532 | |||
| 533 | case BURN_RESUME_MODE_REBOOT_PENDING: | ||
| 534 | // The volatile pending registry doesn't exist (checked above) which means | ||
| 535 | // the system was successfully restarted. | ||
| 536 | *pResumeType = BOOTSTRAPPER_RESUME_TYPE_REBOOT; | ||
| 537 | break; | ||
| 538 | 514 | ||
| 539 | default: | 515 | if (BOOTSTRAPPER_RESUME_TYPE_NONE == *pResumeType) |
| 540 | // the value stored in the registry is not valid | 516 | { |
| 541 | *pResumeType = BOOTSTRAPPER_RESUME_TYPE_INVALID; | 517 | hr = RegistrationDetectResumeTypeByHive(HKEY_CURRENT_USER, pRegistration, pResumeType); |
| 542 | break; | 518 | } |
| 543 | } | 519 | } |
| 520 | ExitOnFailure(hr, "Failed to find bundle registration: %ls", pRegistration->sczRegistrationKey); | ||
| 544 | 521 | ||
| 545 | LExit: | 522 | LExit: |
| 546 | ReleaseRegKey(hkRegistration); | ||
| 547 | |||
| 548 | return hr; | 523 | return hr; |
| 549 | } | 524 | } |
| 550 | 525 | ||
| @@ -889,7 +864,7 @@ extern "C" HRESULT RegistrationSessionEnd( | |||
| 889 | 864 | ||
| 890 | // Open registration key. | 865 | // Open registration key. |
| 891 | hr = RegOpen(pRegistration->hkRoot, pRegistration->sczRegistrationKey, KEY_WRITE, &hkRegistration); | 866 | hr = RegOpen(pRegistration->hkRoot, pRegistration->sczRegistrationKey, KEY_WRITE, &hkRegistration); |
| 892 | ExitOnFailure(hr, "Failed to open registration key."); | 867 | ExitOnFailure(hr, "Failed to open registration key for ending session."); |
| 893 | 868 | ||
| 894 | // update display name | 869 | // update display name |
| 895 | hr = UpdateBundleNameRegistration(pRegistration, pVariables, hkRegistration, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS == registrationType); | 870 | hr = UpdateBundleNameRegistration(pRegistration, pVariables, hkRegistration, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS == registrationType); |
| @@ -1068,6 +1043,39 @@ extern "C" HRESULT RegistrationGetResumeCommandLine( | |||
| 1068 | return hr; | 1043 | return hr; |
| 1069 | } | 1044 | } |
| 1070 | 1045 | ||
| 1046 | extern "C" HRESULT RegistrationSetPaths( | ||
| 1047 | __in BURN_REGISTRATION* pRegistration, | ||
| 1048 | __in BURN_CACHE* pCache | ||
| 1049 | ) | ||
| 1050 | { | ||
| 1051 | HRESULT hr = S_OK; | ||
| 1052 | LPWSTR sczCacheDirectory = NULL; | ||
| 1053 | |||
| 1054 | // save registration key root | ||
| 1055 | pRegistration->hkRoot = pRegistration->fPerMachine ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; | ||
| 1056 | |||
| 1057 | // build uninstall registry key path | ||
| 1058 | hr = StrAllocFormatted(&pRegistration->sczRegistrationKey, L"%ls\\%ls", BURN_REGISTRATION_REGISTRY_UNINSTALL_KEY, pRegistration->sczCode); | ||
| 1059 | ExitOnFailure(hr, "Failed to build uninstall registry key path."); | ||
| 1060 | |||
| 1061 | // build cache directory | ||
| 1062 | hr = CacheGetCompletedPath(pCache, pRegistration->fPerMachine, pRegistration->sczCode, &sczCacheDirectory); | ||
| 1063 | ExitOnFailure(hr, "Failed to build cache directory."); | ||
| 1064 | |||
| 1065 | // build cached executable path | ||
| 1066 | hr = PathConcatRelativeToFullyQualifiedBase(sczCacheDirectory, pRegistration->sczExecutableName, &pRegistration->sczCacheExecutablePath); | ||
| 1067 | ExitOnFailure(hr, "Failed to build cached executable path."); | ||
| 1068 | |||
| 1069 | // build state file path | ||
| 1070 | hr = StrAllocFormatted(&pRegistration->sczStateFile, L"%ls\\state.rsm", sczCacheDirectory); | ||
| 1071 | ExitOnFailure(hr, "Failed to build state file path."); | ||
| 1072 | |||
| 1073 | LExit: | ||
| 1074 | ReleaseStr(sczCacheDirectory); | ||
| 1075 | |||
| 1076 | return hr; | ||
| 1077 | } | ||
| 1078 | |||
| 1071 | 1079 | ||
| 1072 | // internal helper functions | 1080 | // internal helper functions |
| 1073 | 1081 | ||
| @@ -1141,38 +1149,6 @@ LExit: | |||
| 1141 | return hr; | 1149 | return hr; |
| 1142 | } | 1150 | } |
| 1143 | 1151 | ||
| 1144 | static HRESULT SetPaths( | ||
| 1145 | __in BURN_REGISTRATION* pRegistration, | ||
| 1146 | __in BURN_CACHE* pCache | ||
| 1147 | ) | ||
| 1148 | { | ||
| 1149 | HRESULT hr = S_OK; | ||
| 1150 | LPWSTR sczCacheDirectory = NULL; | ||
| 1151 | |||
| 1152 | // save registration key root | ||
| 1153 | pRegistration->hkRoot = pRegistration->fPerMachine ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; | ||
| 1154 | |||
| 1155 | // build uninstall registry key path | ||
| 1156 | hr = StrAllocFormatted(&pRegistration->sczRegistrationKey, L"%ls\\%ls", BURN_REGISTRATION_REGISTRY_UNINSTALL_KEY, pRegistration->sczCode); | ||
| 1157 | ExitOnFailure(hr, "Failed to build uninstall registry key path."); | ||
| 1158 | |||
| 1159 | // build cache directory | ||
| 1160 | hr = CacheGetCompletedPath(pCache, pRegistration->fPerMachine, pRegistration->sczCode, &sczCacheDirectory); | ||
| 1161 | ExitOnFailure(hr, "Failed to build cache directory."); | ||
| 1162 | |||
| 1163 | // build cached executable path | ||
| 1164 | hr = PathConcatRelativeToFullyQualifiedBase(sczCacheDirectory, pRegistration->sczExecutableName, &pRegistration->sczCacheExecutablePath); | ||
| 1165 | ExitOnFailure(hr, "Failed to build cached executable path."); | ||
| 1166 | |||
| 1167 | // build state file path | ||
| 1168 | hr = StrAllocFormatted(&pRegistration->sczStateFile, L"%ls\\state.rsm", sczCacheDirectory); | ||
| 1169 | ExitOnFailure(hr, "Failed to build state file path."); | ||
| 1170 | |||
| 1171 | LExit: | ||
| 1172 | ReleaseStr(sczCacheDirectory); | ||
| 1173 | return hr; | ||
| 1174 | } | ||
| 1175 | |||
| 1176 | static HRESULT GetBundleManufacturer( | 1152 | static HRESULT GetBundleManufacturer( |
| 1177 | __in BURN_REGISTRATION* pRegistration, | 1153 | __in BURN_REGISTRATION* pRegistration, |
| 1178 | __in BURN_VARIABLES* pVariables, | 1154 | __in BURN_VARIABLES* pVariables, |
| @@ -1703,3 +1679,102 @@ static BOOL IsRegistryRebootPending() | |||
| 1703 | 1679 | ||
| 1704 | return fRebootPending; | 1680 | return fRebootPending; |
| 1705 | } | 1681 | } |
| 1682 | |||
| 1683 | static HRESULT RegistrationDetectResumeTypeByHive( | ||
| 1684 | __in HKEY hkRegistrationRoot, | ||
| 1685 | __in BURN_REGISTRATION* pRegistration, | ||
| 1686 | __out BOOTSTRAPPER_RESUME_TYPE* pResumeType | ||
| 1687 | ) | ||
| 1688 | { | ||
| 1689 | HRESULT hr = S_OK; | ||
| 1690 | HKEY hkRegistration = NULL; | ||
| 1691 | BOOL fExists = FALSE; | ||
| 1692 | DWORD dwResume = 0; | ||
| 1693 | |||
| 1694 | *pResumeType = BOOTSTRAPPER_RESUME_TYPE_NONE; | ||
| 1695 | |||
| 1696 | // open registration key | ||
| 1697 | hr = RegOpen(hkRegistrationRoot, pRegistration->sczRegistrationKey, KEY_QUERY_VALUE, &hkRegistration); | ||
| 1698 | ExitOnPathFailure(hr, fExists, "Failed to open registration key."); | ||
| 1699 | |||
| 1700 | if (!fExists) | ||
| 1701 | { | ||
| 1702 | *pResumeType = BOOTSTRAPPER_RESUME_TYPE_NONE; | ||
| 1703 | ExitFunction(); | ||
| 1704 | } | ||
| 1705 | |||
| 1706 | // read Resume value | ||
| 1707 | hr = RegReadNumber(hkRegistration, L"Resume", &dwResume); | ||
| 1708 | ExitOnPathFailure(hr, fExists, "Failed to read Resume value."); | ||
| 1709 | |||
| 1710 | if (!fExists) | ||
| 1711 | { | ||
| 1712 | *pResumeType = BOOTSTRAPPER_RESUME_TYPE_INVALID; | ||
| 1713 | ExitFunction(); | ||
| 1714 | } | ||
| 1715 | |||
| 1716 | switch (dwResume) | ||
| 1717 | { | ||
| 1718 | case BURN_RESUME_MODE_ACTIVE: | ||
| 1719 | // a previous run was interrupted | ||
| 1720 | *pResumeType = BOOTSTRAPPER_RESUME_TYPE_INTERRUPTED; | ||
| 1721 | break; | ||
| 1722 | |||
| 1723 | case BURN_RESUME_MODE_SUSPEND: | ||
| 1724 | *pResumeType = BOOTSTRAPPER_RESUME_TYPE_SUSPEND; | ||
| 1725 | break; | ||
| 1726 | |||
| 1727 | case BURN_RESUME_MODE_ARP: | ||
| 1728 | *pResumeType = BOOTSTRAPPER_RESUME_TYPE_ARP; | ||
| 1729 | break; | ||
| 1730 | |||
| 1731 | case BURN_RESUME_MODE_REBOOT_PENDING: | ||
| 1732 | // The volatile pending registry doesn't exist (checked above) which means | ||
| 1733 | // the system was successfully restarted. | ||
| 1734 | *pResumeType = BOOTSTRAPPER_RESUME_TYPE_REBOOT; | ||
| 1735 | break; | ||
| 1736 | |||
| 1737 | default: | ||
| 1738 | // the value stored in the registry is not valid | ||
| 1739 | *pResumeType = BOOTSTRAPPER_RESUME_TYPE_INVALID; | ||
| 1740 | break; | ||
| 1741 | } | ||
| 1742 | |||
| 1743 | LExit: | ||
| 1744 | ReleaseRegKey(hkRegistration); | ||
| 1745 | |||
| 1746 | return hr; | ||
| 1747 | } | ||
| 1748 | |||
| 1749 | static HRESULT DetectInstalled( | ||
| 1750 | __in BURN_REGISTRATION* pRegistration, | ||
| 1751 | __in HKEY hkRoot | ||
| 1752 | ) | ||
| 1753 | { | ||
| 1754 | HRESULT hr = S_OK; | ||
| 1755 | HKEY hkRegistration = NULL; | ||
| 1756 | DWORD dwInstalled = 0; | ||
| 1757 | |||
| 1758 | pRegistration->fCached = pRegistration->sczCacheExecutablePath && FileExistsEx(pRegistration->sczCacheExecutablePath, NULL); | ||
| 1759 | pRegistration->detectedRegistrationType = BOOTSTRAPPER_REGISTRATION_TYPE_NONE; | ||
| 1760 | |||
| 1761 | // open registration key | ||
| 1762 | hr = RegOpen(hkRoot, pRegistration->sczRegistrationKey, KEY_QUERY_VALUE, &hkRegistration); | ||
| 1763 | if (SUCCEEDED(hr)) | ||
| 1764 | { | ||
| 1765 | hr = RegReadNumber(hkRegistration, REGISTRY_BUNDLE_INSTALLED, &dwInstalled); | ||
| 1766 | |||
| 1767 | pRegistration->detectedRegistrationType = (1 == dwInstalled) ? BOOTSTRAPPER_REGISTRATION_TYPE_FULL : BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS; | ||
| 1768 | } | ||
| 1769 | |||
| 1770 | // Not finding the key or value is okay. | ||
| 1771 | if (E_FILENOTFOUND == hr || E_PATHNOTFOUND == hr) | ||
| 1772 | { | ||
| 1773 | hr = S_OK; | ||
| 1774 | } | ||
| 1775 | |||
| 1776 | ReleaseRegKey(hkRegistration); | ||
| 1777 | |||
| 1778 | return hr; | ||
| 1779 | } | ||
| 1780 | |||
diff --git a/src/burn/engine/registration.h b/src/burn/engine/registration.h index 326f21c6..e83b75b6 100644 --- a/src/burn/engine/registration.h +++ b/src/burn/engine/registration.h | |||
| @@ -94,11 +94,12 @@ typedef struct _BURN_SOFTWARE_TAGS | |||
| 94 | 94 | ||
| 95 | typedef struct _BURN_REGISTRATION | 95 | typedef struct _BURN_REGISTRATION |
| 96 | { | 96 | { |
| 97 | BOOL fPerMachine; | 97 | BOOL fPerMachine; // For PUOM/PMOU bundles, only valid after planning. |
| 98 | BOOL fForceSystemComponent; | 98 | BOOL fForceSystemComponent; |
| 99 | BOOL fDisableResume; | 99 | BOOL fDisableResume; |
| 100 | BOOL fCached; | 100 | BOOL fCached; |
| 101 | BOOTSTRAPPER_REGISTRATION_TYPE detectedRegistrationType; | 101 | BOOTSTRAPPER_REGISTRATION_TYPE detectedRegistrationType; |
| 102 | BOOTSTRAPPER_PACKAGE_SCOPE scope; | ||
| 102 | LPWSTR sczCode; | 103 | LPWSTR sczCode; |
| 103 | LPWSTR sczTag; | 104 | LPWSTR sczTag; |
| 104 | 105 | ||
| @@ -167,7 +168,7 @@ HRESULT RegistrationParseFromXml( | |||
| 167 | __in BURN_REGISTRATION* pRegistration, | 168 | __in BURN_REGISTRATION* pRegistration, |
| 168 | __in BURN_CACHE* pCache, | 169 | __in BURN_CACHE* pCache, |
| 169 | __in IXMLDOMNode* pixnBundle | 170 | __in IXMLDOMNode* pixnBundle |
| 170 | ); | 171 | ); |
| 171 | void RegistrationUninitialize( | 172 | void RegistrationUninitialize( |
| 172 | __in BURN_REGISTRATION* pRegistration | 173 | __in BURN_REGISTRATION* pRegistration |
| 173 | ); | 174 | ); |
| @@ -191,7 +192,7 @@ HRESULT RegistrationDetectRelatedBundles( | |||
| 191 | ); | 192 | ); |
| 192 | HRESULT RegistrationPlanInitialize( | 193 | HRESULT RegistrationPlanInitialize( |
| 193 | __in BURN_REGISTRATION* pRegistration | 194 | __in BURN_REGISTRATION* pRegistration |
| 194 | ); | 195 | ); |
| 195 | HRESULT RegistrationSessionBegin( | 196 | HRESULT RegistrationSessionBegin( |
| 196 | __in_z LPCWSTR wzEngineWorkingPath, | 197 | __in_z LPCWSTR wzEngineWorkingPath, |
| 197 | __in BURN_REGISTRATION* pRegistration, | 198 | __in BURN_REGISTRATION* pRegistration, |
| @@ -225,6 +226,10 @@ HRESULT RegistrationGetResumeCommandLine( | |||
| 225 | __in const BURN_REGISTRATION* pRegistration, | 226 | __in const BURN_REGISTRATION* pRegistration, |
| 226 | __deref_out_z LPWSTR* psczResumeCommandLine | 227 | __deref_out_z LPWSTR* psczResumeCommandLine |
| 227 | ); | 228 | ); |
| 229 | HRESULT RegistrationSetPaths( | ||
| 230 | __in BURN_REGISTRATION* pRegistration, | ||
| 231 | __in BURN_CACHE* pCache | ||
| 232 | ); | ||
| 228 | 233 | ||
| 229 | 234 | ||
| 230 | #if defined(__cplusplus) | 235 | #if defined(__cplusplus) |
diff --git a/src/burn/engine/relatedbundle.cpp b/src/burn/engine/relatedbundle.cpp index c9aa7170..d0b97af0 100644 --- a/src/burn/engine/relatedbundle.cpp +++ b/src/burn/engine/relatedbundle.cpp | |||
| @@ -22,7 +22,7 @@ static __callback int __cdecl CompareRelatedBundlesPlan( | |||
| 22 | ); | 22 | ); |
| 23 | static BUNDLE_QUERY_CALLBACK_RESULT CALLBACK QueryRelatedBundlesCallback( | 23 | static BUNDLE_QUERY_CALLBACK_RESULT CALLBACK QueryRelatedBundlesCallback( |
| 24 | __in const BUNDLE_QUERY_RELATED_BUNDLE_RESULT* pBundle, | 24 | __in const BUNDLE_QUERY_RELATED_BUNDLE_RESULT* pBundle, |
| 25 | __in_opt LPVOID pvContext | 25 | __in LPVOID pvContext |
| 26 | ); | 26 | ); |
| 27 | static HRESULT LoadIfRelatedBundle( | 27 | static HRESULT LoadIfRelatedBundle( |
| 28 | __in const BUNDLE_QUERY_RELATED_BUNDLE_RESULT* pBundle, | 28 | __in const BUNDLE_QUERY_RELATED_BUNDLE_RESULT* pBundle, |
| @@ -258,7 +258,7 @@ static __callback int __cdecl CompareRelatedBundlesPlan( | |||
| 258 | 258 | ||
| 259 | static BUNDLE_QUERY_CALLBACK_RESULT CALLBACK QueryRelatedBundlesCallback( | 259 | static BUNDLE_QUERY_CALLBACK_RESULT CALLBACK QueryRelatedBundlesCallback( |
| 260 | __in const BUNDLE_QUERY_RELATED_BUNDLE_RESULT* pBundle, | 260 | __in const BUNDLE_QUERY_RELATED_BUNDLE_RESULT* pBundle, |
| 261 | __in_opt LPVOID pvContext | 261 | __in LPVOID pvContext |
| 262 | ) | 262 | ) |
| 263 | { | 263 | { |
| 264 | HRESULT hr = S_OK; | 264 | HRESULT hr = S_OK; |
diff --git a/src/burn/engine/uithread.cpp b/src/burn/engine/uithread.cpp index 9beb9f80..1f7db965 100644 --- a/src/burn/engine/uithread.cpp +++ b/src/burn/engine/uithread.cpp | |||
| @@ -123,7 +123,7 @@ static DWORD WINAPI ThreadProc( | |||
| 123 | info.pEngineState = pEngineState; | 123 | info.pEngineState = pEngineState; |
| 124 | 124 | ||
| 125 | // Create the window to handle reboots without activating it. | 125 | // Create the window to handle reboots without activating it. |
| 126 | hWnd = ::CreateWindowExW(WS_EX_NOACTIVATE, wc.lpszClassName, NULL, WS_POPUP, 0, 0, 0, 0, HWND_DESKTOP, NULL, pContext->hInstance, &info); | 126 | hWnd = ::CreateWindowExW(WS_EX_NOACTIVATE, wc.lpszClassName, BURN_UITHREAD_CLASS_WINDOW, WS_POPUP, 0, 0, 0, 0, HWND_DESKTOP, NULL, pContext->hInstance, &info); |
| 127 | ExitOnNullWithLastError(hWnd, hr, "Failed to create Burn UI thread window."); | 127 | ExitOnNullWithLastError(hWnd, hr, "Failed to create Burn UI thread window."); |
| 128 | 128 | ||
| 129 | ::ShowWindow(hWnd, SW_SHOWNA); | 129 | ::ShowWindow(hWnd, SW_SHOWNA); |
diff --git a/src/burn/engine/variable.cpp b/src/burn/engine/variable.cpp index a795d76c..1b7dc4d1 100644 --- a/src/burn/engine/variable.cpp +++ b/src/burn/engine/variable.cpp | |||
| @@ -305,6 +305,8 @@ extern "C" HRESULT VariableInitialize( | |||
| 305 | {BURN_BUNDLE_TAG, InitializeVariableString, (DWORD_PTR)L"", FALSE, TRUE}, | 305 | {BURN_BUNDLE_TAG, InitializeVariableString, (DWORD_PTR)L"", FALSE, TRUE}, |
| 306 | {BURN_BUNDLE_UILEVEL, InitializeVariableNumeric, 0, FALSE, TRUE}, | 306 | {BURN_BUNDLE_UILEVEL, InitializeVariableNumeric, 0, FALSE, TRUE}, |
| 307 | {BURN_BUNDLE_VERSION, InitializeVariableVersion, (DWORD_PTR)L"0", FALSE, TRUE}, | 307 | {BURN_BUNDLE_VERSION, InitializeVariableVersion, (DWORD_PTR)L"0", FALSE, TRUE}, |
| 308 | {BURN_BUNDLE_SCOPE, InitializeVariableNumeric, 0, FALSE, TRUE}, | ||
| 309 | {BURN_BUNDLE_PLANNED_SCOPE, InitializeVariableNumeric, 0, FALSE, TRUE}, | ||
| 308 | }; | 310 | }; |
| 309 | 311 | ||
| 310 | const WELL_KNOWN_VARIABLE_DECLARATION vrgWellKnownVariableNames[] = | 312 | const WELL_KNOWN_VARIABLE_DECLARATION vrgWellKnownVariableNames[] = |
