aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2022-01-31 15:44:00 -0600
committerSean Hall <r.sean.hall@gmail.com>2022-02-01 23:36:23 -0600
commit56c980318e7167be591f7807c2fc34cea7d5cb42 (patch)
treee074b3548d8dfe51f420b6d0278a6fe17191b6ec
parentbfe5ab76b5ecc1a21078534e6fba90d12cfd3c00 (diff)
downloadwix-56c980318e7167be591f7807c2fc34cea7d5cb42.tar.gz
wix-56c980318e7167be591f7807c2fc34cea7d5cb42.tar.bz2
wix-56c980318e7167be591f7807c2fc34cea7d5cb42.zip
The bundle provider's presence needs to follow ARP registration.
-rw-r--r--src/burn/engine/apply.cpp41
-rw-r--r--src/burn/engine/approvedexe.h2
-rw-r--r--src/burn/engine/dependency.cpp5
-rw-r--r--src/burn/engine/detect.cpp4
-rw-r--r--src/burn/engine/elevation.cpp18
-rw-r--r--src/burn/engine/elevation.h4
-rw-r--r--src/burn/engine/engine.mc7
-rw-r--r--src/burn/engine/plan.cpp23
-rw-r--r--src/burn/engine/plan.h12
-rw-r--r--src/burn/engine/registration.cpp320
-rw-r--r--src/burn/engine/registration.h8
-rw-r--r--src/burn/test/BurnUnitTest/RegistrationTest.cpp42
12 files changed, 233 insertions, 253 deletions
diff --git a/src/burn/engine/apply.cpp b/src/burn/engine/apply.cpp
index 6bf3020c..9185e33a 100644
--- a/src/burn/engine/apply.cpp
+++ b/src/burn/engine/apply.cpp
@@ -432,12 +432,12 @@ extern "C" HRESULT ApplyRegister(
432 // begin new session 432 // begin new session
433 if (pEngineState->registration.fPerMachine) 433 if (pEngineState->registration.fPerMachine)
434 { 434 {
435 hr = ElevationSessionBegin(pEngineState->companionConnection.hPipe, sczEngineWorkingPath, pEngineState->registration.sczResumeCommandLine, pEngineState->registration.fDisableResume, &pEngineState->variables, pEngineState->plan.dwRegistrationOperations, pEngineState->plan.dependencyRegistrationAction, pEngineState->plan.qwEstimatedSize, registrationType); 435 hr = ElevationSessionBegin(pEngineState->companionConnection.hPipe, sczEngineWorkingPath, pEngineState->registration.sczResumeCommandLine, pEngineState->registration.fDisableResume, &pEngineState->variables, pEngineState->plan.dwRegistrationOperations, pEngineState->registration.fDetectedForeignProviderKeyBundleId, pEngineState->plan.qwEstimatedSize, registrationType);
436 ExitOnFailure(hr, "Failed to begin registration session in per-machine process."); 436 ExitOnFailure(hr, "Failed to begin registration session in per-machine process.");
437 } 437 }
438 else 438 else
439 { 439 {
440 hr = RegistrationSessionBegin(sczEngineWorkingPath, &pEngineState->registration, &pEngineState->cache, &pEngineState->variables, pEngineState->plan.dwRegistrationOperations, pEngineState->plan.dependencyRegistrationAction, pEngineState->plan.qwEstimatedSize, registrationType); 440 hr = RegistrationSessionBegin(sczEngineWorkingPath, &pEngineState->registration, &pEngineState->cache, &pEngineState->variables, pEngineState->plan.dwRegistrationOperations, pEngineState->plan.qwEstimatedSize, registrationType);
441 ExitOnFailure(hr, "Failed to begin registration session."); 441 ExitOnFailure(hr, "Failed to begin registration session.");
442 } 442 }
443 } 443 }
@@ -521,12 +521,12 @@ extern "C" HRESULT ApplyUnregister(
521 521
522 if (pEngineState->registration.fPerMachine) 522 if (pEngineState->registration.fPerMachine)
523 { 523 {
524 hr = ElevationSessionEnd(pEngineState->companionConnection.hPipe, resumeMode, restart, pEngineState->plan.dependencyRegistrationAction, registrationType); 524 hr = ElevationSessionEnd(pEngineState->companionConnection.hPipe, resumeMode, restart, pEngineState->registration.fDetectedForeignProviderKeyBundleId, registrationType);
525 ExitOnFailure(hr, "Failed to end session in per-machine process."); 525 ExitOnFailure(hr, "Failed to end session in per-machine process.");
526 } 526 }
527 else 527 else
528 { 528 {
529 hr = RegistrationSessionEnd(&pEngineState->registration, &pEngineState->cache, &pEngineState->variables, &pEngineState->packages, resumeMode, restart, pEngineState->plan.dependencyRegistrationAction, registrationType); 529 hr = RegistrationSessionEnd(&pEngineState->registration, &pEngineState->cache, &pEngineState->variables, &pEngineState->packages, resumeMode, restart, registrationType);
530 ExitOnFailure(hr, "Failed to end session in per-user process."); 530 ExitOnFailure(hr, "Failed to end session in per-user process.");
531 } 531 }
532 532
@@ -2914,8 +2914,9 @@ static HRESULT ExecuteDependencyAction(
2914 ) 2914 )
2915{ 2915{
2916 HRESULT hr = S_OK; 2916 HRESULT hr = S_OK;
2917 BURN_PACKAGE* pPackage = pAction->packageDependency.pPackage;
2917 2918
2918 if (pAction->packageDependency.pPackage->fPerMachine) 2919 if (pPackage->fPerMachine)
2919 { 2920 {
2920 hr = ElevationExecutePackageDependencyAction(pEngineState->companionConnection.hPipe, pAction); 2921 hr = ElevationExecutePackageDependencyAction(pEngineState->companionConnection.hPipe, pAction);
2921 ExitOnFailure(hr, "Failed to register the dependency on per-machine package."); 2922 ExitOnFailure(hr, "Failed to register the dependency on per-machine package.");
@@ -2926,20 +2927,20 @@ static HRESULT ExecuteDependencyAction(
2926 ExitOnFailure(hr, "Failed to register the dependency on per-user package."); 2927 ExitOnFailure(hr, "Failed to register the dependency on per-user package.");
2927 } 2928 }
2928 2929
2929 if (pAction->packageDependency.pPackage->fCanAffectRegistration) 2930 if (pPackage->fCanAffectRegistration)
2930 { 2931 {
2931 if (BURN_DEPENDENCY_ACTION_REGISTER == pAction->packageDependency.action) 2932 if (BURN_DEPENDENCY_ACTION_REGISTER == pAction->packageDependency.action)
2932 { 2933 {
2933 if (BURN_PACKAGE_REGISTRATION_STATE_IGNORED == pAction->packageDependency.pPackage->cacheRegistrationState) 2934 if (BURN_PACKAGE_REGISTRATION_STATE_IGNORED == pPackage->cacheRegistrationState)
2934 { 2935 {
2935 pAction->packageDependency.pPackage->cacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT; 2936 pPackage->cacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT;
2936 } 2937 }
2937 2938
2938 if (BURN_PACKAGE_TYPE_MSP == pAction->packageDependency.pPackage->type) 2939 if (BURN_PACKAGE_TYPE_MSP == pPackage->type)
2939 { 2940 {
2940 for (DWORD i = 0; i < pAction->packageDependency.pPackage->Msp.cTargetProductCodes; ++i) 2941 for (DWORD i = 0; i < pPackage->Msp.cTargetProductCodes; ++i)
2941 { 2942 {
2942 BURN_MSPTARGETPRODUCT* pTargetProduct = pAction->packageDependency.pPackage->Msp.rgTargetProducts + i; 2943 BURN_MSPTARGETPRODUCT* pTargetProduct = pPackage->Msp.rgTargetProducts + i;
2943 2944
2944 if (BURN_PACKAGE_REGISTRATION_STATE_IGNORED == pTargetProduct->registrationState) 2945 if (BURN_PACKAGE_REGISTRATION_STATE_IGNORED == pTargetProduct->registrationState)
2945 { 2946 {
@@ -2947,23 +2948,23 @@ static HRESULT ExecuteDependencyAction(
2947 } 2948 }
2948 } 2949 }
2949 } 2950 }
2950 else if (BURN_PACKAGE_REGISTRATION_STATE_IGNORED == pAction->packageDependency.pPackage->installRegistrationState) 2951 else if (BURN_PACKAGE_REGISTRATION_STATE_IGNORED == pPackage->installRegistrationState)
2951 { 2952 {
2952 pAction->packageDependency.pPackage->installRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT; 2953 pPackage->installRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT;
2953 } 2954 }
2954 } 2955 }
2955 else if (BURN_DEPENDENCY_ACTION_UNREGISTER == pAction->packageDependency.action) 2956 else if (BURN_DEPENDENCY_ACTION_UNREGISTER == pAction->packageDependency.action)
2956 { 2957 {
2957 if (BURN_PACKAGE_REGISTRATION_STATE_PRESENT == pAction->packageDependency.pPackage->cacheRegistrationState) 2958 if (BURN_PACKAGE_REGISTRATION_STATE_PRESENT == pPackage->cacheRegistrationState)
2958 { 2959 {
2959 pAction->packageDependency.pPackage->cacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_IGNORED; 2960 pPackage->cacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_IGNORED;
2960 } 2961 }
2961 2962
2962 if (BURN_PACKAGE_TYPE_MSP == pAction->packageDependency.pPackage->type) 2963 if (BURN_PACKAGE_TYPE_MSP == pPackage->type)
2963 { 2964 {
2964 for (DWORD i = 0; i < pAction->packageDependency.pPackage->Msp.cTargetProductCodes; ++i) 2965 for (DWORD i = 0; i < pPackage->Msp.cTargetProductCodes; ++i)
2965 { 2966 {
2966 BURN_MSPTARGETPRODUCT* pTargetProduct = pAction->packageDependency.pPackage->Msp.rgTargetProducts + i; 2967 BURN_MSPTARGETPRODUCT* pTargetProduct = pPackage->Msp.rgTargetProducts + i;
2967 2968
2968 if (BURN_PACKAGE_REGISTRATION_STATE_PRESENT == pTargetProduct->registrationState) 2969 if (BURN_PACKAGE_REGISTRATION_STATE_PRESENT == pTargetProduct->registrationState)
2969 { 2970 {
@@ -2971,9 +2972,9 @@ static HRESULT ExecuteDependencyAction(
2971 } 2972 }
2972 } 2973 }
2973 } 2974 }
2974 else if (BURN_PACKAGE_REGISTRATION_STATE_PRESENT == pAction->packageDependency.pPackage->installRegistrationState) 2975 else if (BURN_PACKAGE_REGISTRATION_STATE_PRESENT == pPackage->installRegistrationState)
2975 { 2976 {
2976 pAction->packageDependency.pPackage->installRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_IGNORED; 2977 pPackage->installRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_IGNORED;
2977 } 2978 }
2978 } 2979 }
2979 } 2980 }
diff --git a/src/burn/engine/approvedexe.h b/src/burn/engine/approvedexe.h
index cd3bf271..8a3f6779 100644
--- a/src/burn/engine/approvedexe.h
+++ b/src/burn/engine/approvedexe.h
@@ -8,10 +8,12 @@ extern "C" {
8 8
9// forward declare 9// forward declare
10 10
11enum BURN_MODE;
11typedef struct _BOOTSTRAPPER_ENGINE_CONTEXT BOOTSTRAPPER_ENGINE_CONTEXT; 12typedef struct _BOOTSTRAPPER_ENGINE_CONTEXT BOOTSTRAPPER_ENGINE_CONTEXT;
12typedef struct _BURN_CACHE BURN_CACHE; 13typedef struct _BURN_CACHE BURN_CACHE;
13typedef struct _BURN_DEPENDENCIES BURN_DEPENDENCIES; 14typedef struct _BURN_DEPENDENCIES BURN_DEPENDENCIES;
14typedef struct _BURN_ENGINE_COMMAND BURN_ENGINE_COMMAND; 15typedef struct _BURN_ENGINE_COMMAND BURN_ENGINE_COMMAND;
16typedef struct _BURN_LOGGING BURN_LOGGING;
15 17
16// structs 18// structs
17 19
diff --git a/src/burn/engine/dependency.cpp b/src/burn/engine/dependency.cpp
index 6ee95935..ce183a8a 100644
--- a/src/burn/engine/dependency.cpp
+++ b/src/burn/engine/dependency.cpp
@@ -246,6 +246,11 @@ extern "C" HRESULT DependencyDetectProviderKeyBundleId(
246 hr = StrAllocString(&pRegistration->sczDetectedProviderKeyBundleId, pRegistration->sczProviderKey, 0); 246 hr = StrAllocString(&pRegistration->sczDetectedProviderKeyBundleId, pRegistration->sczProviderKey, 0);
247 ExitOnFailure(hr, "Failed to initialize provider key bundle id."); 247 ExitOnFailure(hr, "Failed to initialize provider key bundle id.");
248 } 248 }
249 else if (CSTR_EQUAL != ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, pRegistration->sczId, -1, pRegistration->sczDetectedProviderKeyBundleId, -1))
250 {
251 pRegistration->fDetectedForeignProviderKeyBundleId = TRUE;
252 LogId(REPORT_STANDARD, MSG_DETECTED_FOREIGN_BUNDLE_PROVIDER_REGISTRATION, pRegistration->sczProviderKey, pRegistration->sczDetectedProviderKeyBundleId);
253 }
249 254
250LExit: 255LExit:
251 return hr; 256 return hr;
diff --git a/src/burn/engine/detect.cpp b/src/burn/engine/detect.cpp
index 37b034ae..617b418b 100644
--- a/src/burn/engine/detect.cpp
+++ b/src/burn/engine/detect.cpp
@@ -39,6 +39,7 @@ extern "C" void DetectReset(
39{ 39{
40 RelatedBundlesUninitialize(&pRegistration->relatedBundles); 40 RelatedBundlesUninitialize(&pRegistration->relatedBundles);
41 ReleaseNullStr(pRegistration->sczDetectedProviderKeyBundleId); 41 ReleaseNullStr(pRegistration->sczDetectedProviderKeyBundleId);
42 pRegistration->fDetectedForeignProviderKeyBundleId = FALSE;
42 pRegistration->fSelfRegisteredAsDependent = FALSE; 43 pRegistration->fSelfRegisteredAsDependent = FALSE;
43 pRegistration->fParentRegisteredAsDependent = FALSE; 44 pRegistration->fParentRegisteredAsDependent = FALSE;
44 pRegistration->fForwardCompatibleBundleExists = FALSE; 45 pRegistration->fForwardCompatibleBundleExists = FALSE;
@@ -118,8 +119,7 @@ extern "C" HRESULT DetectForwardCompatibleBundles(
118 HRESULT hr = S_OK; 119 HRESULT hr = S_OK;
119 int nCompareResult = 0; 120 int nCompareResult = 0;
120 121
121 if (pRegistration->sczDetectedProviderKeyBundleId && 122 if (pRegistration->fDetectedForeignProviderKeyBundleId)
122 CSTR_EQUAL != ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, pRegistration->sczDetectedProviderKeyBundleId, -1, pRegistration->sczId, -1))
123 { 123 {
124 for (DWORD iRelatedBundle = 0; iRelatedBundle < pRegistration->relatedBundles.cRelatedBundles; ++iRelatedBundle) 124 for (DWORD iRelatedBundle = 0; iRelatedBundle < pRegistration->relatedBundles.cRelatedBundles; ++iRelatedBundle)
125 { 125 {
diff --git a/src/burn/engine/elevation.cpp b/src/burn/engine/elevation.cpp
index 9ebba7c5..eafc08ee 100644
--- a/src/burn/engine/elevation.cpp
+++ b/src/burn/engine/elevation.cpp
@@ -525,7 +525,7 @@ extern "C" HRESULT ElevationSessionBegin(
525 __in BOOL fDisableResume, 525 __in BOOL fDisableResume,
526 __in BURN_VARIABLES* pVariables, 526 __in BURN_VARIABLES* pVariables,
527 __in DWORD dwRegistrationOperations, 527 __in DWORD dwRegistrationOperations,
528 __in BURN_DEPENDENCY_REGISTRATION_ACTION dependencyRegistrationAction, 528 __in BOOL fDetectedForeignProviderKeyBundleId,
529 __in DWORD64 qwEstimatedSize, 529 __in DWORD64 qwEstimatedSize,
530 __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType 530 __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType
531 ) 531 )
@@ -548,7 +548,7 @@ extern "C" HRESULT ElevationSessionBegin(
548 hr = BuffWriteNumber(&pbData, &cbData, dwRegistrationOperations); 548 hr = BuffWriteNumber(&pbData, &cbData, dwRegistrationOperations);
549 ExitOnFailure(hr, "Failed to write registration operations to message buffer."); 549 ExitOnFailure(hr, "Failed to write registration operations to message buffer.");
550 550
551 hr = BuffWriteNumber(&pbData, &cbData, (DWORD)dependencyRegistrationAction); 551 hr = BuffWriteNumber(&pbData, &cbData, (DWORD)fDetectedForeignProviderKeyBundleId);
552 ExitOnFailure(hr, "Failed to write dependency registration action to message buffer."); 552 ExitOnFailure(hr, "Failed to write dependency registration action to message buffer.");
553 553
554 hr = BuffWriteNumber64(&pbData, &cbData, qwEstimatedSize); 554 hr = BuffWriteNumber64(&pbData, &cbData, qwEstimatedSize);
@@ -622,7 +622,7 @@ extern "C" HRESULT ElevationSessionEnd(
622 __in HANDLE hPipe, 622 __in HANDLE hPipe,
623 __in BURN_RESUME_MODE resumeMode, 623 __in BURN_RESUME_MODE resumeMode,
624 __in BOOTSTRAPPER_APPLY_RESTART restart, 624 __in BOOTSTRAPPER_APPLY_RESTART restart,
625 __in BURN_DEPENDENCY_REGISTRATION_ACTION dependencyRegistrationAction, 625 __in BOOL fDetectedForeignProviderKeyBundleId,
626 __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType 626 __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType
627 ) 627 )
628{ 628{
@@ -638,7 +638,7 @@ extern "C" HRESULT ElevationSessionEnd(
638 hr = BuffWriteNumber(&pbData, &cbData, (DWORD)restart); 638 hr = BuffWriteNumber(&pbData, &cbData, (DWORD)restart);
639 ExitOnFailure(hr, "Failed to write restart enum to message buffer."); 639 ExitOnFailure(hr, "Failed to write restart enum to message buffer.");
640 640
641 hr = BuffWriteNumber(&pbData, &cbData, (DWORD)dependencyRegistrationAction); 641 hr = BuffWriteNumber(&pbData, &cbData, (DWORD)fDetectedForeignProviderKeyBundleId);
642 ExitOnFailure(hr, "Failed to write dependency registration action to message buffer."); 642 ExitOnFailure(hr, "Failed to write dependency registration action to message buffer.");
643 643
644 hr = BuffWriteNumber(&pbData, &cbData, (DWORD)registrationType); 644 hr = BuffWriteNumber(&pbData, &cbData, (DWORD)registrationType);
@@ -2359,7 +2359,6 @@ static HRESULT OnSessionBegin(
2359 SIZE_T iData = 0; 2359 SIZE_T iData = 0;
2360 LPWSTR sczEngineWorkingPath = NULL; 2360 LPWSTR sczEngineWorkingPath = NULL;
2361 DWORD dwRegistrationOperations = 0; 2361 DWORD dwRegistrationOperations = 0;
2362 DWORD dwDependencyRegistrationAction = 0;
2363 DWORD64 qwEstimatedSize = 0; 2362 DWORD64 qwEstimatedSize = 0;
2364 DWORD dwRegistrationType = 0; 2363 DWORD dwRegistrationType = 0;
2365 2364
@@ -2376,7 +2375,7 @@ static HRESULT OnSessionBegin(
2376 hr = BuffReadNumber(pbData, cbData, &iData, &dwRegistrationOperations); 2375 hr = BuffReadNumber(pbData, cbData, &iData, &dwRegistrationOperations);
2377 ExitOnFailure(hr, "Failed to read registration operations."); 2376 ExitOnFailure(hr, "Failed to read registration operations.");
2378 2377
2379 hr = BuffReadNumber(pbData, cbData, &iData, &dwDependencyRegistrationAction); 2378 hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&pRegistration->fDetectedForeignProviderKeyBundleId);
2380 ExitOnFailure(hr, "Failed to read dependency registration action."); 2379 ExitOnFailure(hr, "Failed to read dependency registration action.");
2381 2380
2382 hr = BuffReadNumber64(pbData, cbData, &iData, &qwEstimatedSize); 2381 hr = BuffReadNumber64(pbData, cbData, &iData, &qwEstimatedSize);
@@ -2389,7 +2388,7 @@ static HRESULT OnSessionBegin(
2389 ExitOnFailure(hr, "Failed to read variables."); 2388 ExitOnFailure(hr, "Failed to read variables.");
2390 2389
2391 // Begin session in per-machine process. 2390 // Begin session in per-machine process.
2392 hr = RegistrationSessionBegin(sczEngineWorkingPath, pRegistration, pCache, pVariables, dwRegistrationOperations, (BURN_DEPENDENCY_REGISTRATION_ACTION)dwDependencyRegistrationAction, qwEstimatedSize, (BOOTSTRAPPER_REGISTRATION_TYPE)dwRegistrationType); 2391 hr = RegistrationSessionBegin(sczEngineWorkingPath, pRegistration, pCache, pVariables, dwRegistrationOperations, qwEstimatedSize, (BOOTSTRAPPER_REGISTRATION_TYPE)dwRegistrationType);
2393 ExitOnFailure(hr, "Failed to begin registration session."); 2392 ExitOnFailure(hr, "Failed to begin registration session.");
2394 2393
2395LExit: 2394LExit:
@@ -2443,7 +2442,6 @@ static HRESULT OnSessionEnd(
2443 SIZE_T iData = 0; 2442 SIZE_T iData = 0;
2444 DWORD dwResumeMode = 0; 2443 DWORD dwResumeMode = 0;
2445 DWORD dwRestart = 0; 2444 DWORD dwRestart = 0;
2446 DWORD dwDependencyRegistrationAction = 0;
2447 DWORD dwRegistrationType = 0; 2445 DWORD dwRegistrationType = 0;
2448 2446
2449 // Deserialize message data. 2447 // Deserialize message data.
@@ -2453,14 +2451,14 @@ static HRESULT OnSessionEnd(
2453 hr = BuffReadNumber(pbData, cbData, &iData, &dwRestart); 2451 hr = BuffReadNumber(pbData, cbData, &iData, &dwRestart);
2454 ExitOnFailure(hr, "Failed to read restart enum."); 2452 ExitOnFailure(hr, "Failed to read restart enum.");
2455 2453
2456 hr = BuffReadNumber(pbData, cbData, &iData, &dwDependencyRegistrationAction); 2454 hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&pRegistration->fDetectedForeignProviderKeyBundleId);
2457 ExitOnFailure(hr, "Failed to read dependency registration action."); 2455 ExitOnFailure(hr, "Failed to read dependency registration action.");
2458 2456
2459 hr = BuffReadNumber(pbData, cbData, &iData, &dwRegistrationType); 2457 hr = BuffReadNumber(pbData, cbData, &iData, &dwRegistrationType);
2460 ExitOnFailure(hr, "Failed to read dependency registration action."); 2458 ExitOnFailure(hr, "Failed to read dependency registration action.");
2461 2459
2462 // suspend session in per-machine process 2460 // suspend session in per-machine process
2463 hr = RegistrationSessionEnd(pRegistration, pCache, pVariables, pPackages, (BURN_RESUME_MODE)dwResumeMode, (BOOTSTRAPPER_APPLY_RESTART)dwRestart, (BURN_DEPENDENCY_REGISTRATION_ACTION)dwDependencyRegistrationAction, (BOOTSTRAPPER_REGISTRATION_TYPE)dwRegistrationType); 2461 hr = RegistrationSessionEnd(pRegistration, pCache, pVariables, pPackages, (BURN_RESUME_MODE)dwResumeMode, (BOOTSTRAPPER_APPLY_RESTART)dwRestart, (BOOTSTRAPPER_REGISTRATION_TYPE)dwRegistrationType);
2464 ExitOnFailure(hr, "Failed to suspend registration session."); 2462 ExitOnFailure(hr, "Failed to suspend registration session.");
2465 2463
2466LExit: 2464LExit:
diff --git a/src/burn/engine/elevation.h b/src/burn/engine/elevation.h
index b4d0ca83..9659ef89 100644
--- a/src/burn/engine/elevation.h
+++ b/src/burn/engine/elevation.h
@@ -28,7 +28,7 @@ HRESULT ElevationSessionBegin(
28 __in BOOL fDisableResume, 28 __in BOOL fDisableResume,
29 __in BURN_VARIABLES* pVariables, 29 __in BURN_VARIABLES* pVariables,
30 __in DWORD dwRegistrationOperations, 30 __in DWORD dwRegistrationOperations,
31 __in BURN_DEPENDENCY_REGISTRATION_ACTION dependencyRegistrationAction, 31 __in BOOL fDetectedForeignProviderKeyBundleId,
32 __in DWORD64 qwEstimatedSize, 32 __in DWORD64 qwEstimatedSize,
33 __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType 33 __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType
34 ); 34 );
@@ -43,7 +43,7 @@ HRESULT ElevationSessionEnd(
43 __in HANDLE hPipe, 43 __in HANDLE hPipe,
44 __in BURN_RESUME_MODE resumeMode, 44 __in BURN_RESUME_MODE resumeMode,
45 __in BOOTSTRAPPER_APPLY_RESTART restart, 45 __in BOOTSTRAPPER_APPLY_RESTART restart,
46 __in BURN_DEPENDENCY_REGISTRATION_ACTION dependencyRegistrationAction, 46 __in BOOL fDetectedForeignProviderKeyBundleId,
47 __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType 47 __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType
48 ); 48 );
49HRESULT ElevationSaveState( 49HRESULT ElevationSaveState(
diff --git a/src/burn/engine/engine.mc b/src/burn/engine/engine.mc
index 6ce11564..b8c9a2d3 100644
--- a/src/burn/engine/engine.mc
+++ b/src/burn/engine/engine.mc
@@ -275,6 +275,13 @@ Language=English
275Detected related bundle missing from cache: %1!ls!, cache path: %2!ls! 275Detected related bundle missing from cache: %1!ls!, cache path: %2!ls!
276. 276.
277 277
278MessageId=110
279Severity=Success
280SymbolicName=MSG_DETECTED_FOREIGN_BUNDLE_PROVIDER_REGISTRATION
281Language=English
282Detected bundle provider key: %1!ls! that is registered to a different bundle: %2!ls!
283.
284
278MessageId=120 285MessageId=120
279Severity=Warning 286Severity=Warning
280SymbolicName=MSG_DETECT_PACKAGE_NOT_FULLY_CACHED 287SymbolicName=MSG_DETECT_PACKAGE_NOT_FULLY_CACHED
diff --git a/src/burn/engine/plan.cpp b/src/burn/engine/plan.cpp
index 2649ee39..a25b17d7 100644
--- a/src/burn/engine/plan.cpp
+++ b/src/burn/engine/plan.cpp
@@ -541,25 +541,14 @@ extern "C" HRESULT PlanRegistration(
541 pPlan->dwRegistrationOperations |= BURN_REGISTRATION_ACTION_OPERATIONS_CACHE_BUNDLE; 541 pPlan->dwRegistrationOperations |= BURN_REGISTRATION_ACTION_OPERATIONS_CACHE_BUNDLE;
542 } 542 }
543 543
544 // Always write registration since things may have changed or it just needs to be "fixed up".
545 pPlan->dwRegistrationOperations |= BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION;
546
547 // Always update our estimated size registration when installing/modify/repair since things
548 // may have been added or removed or it just needs to be "fixed up".
549 pPlan->dwRegistrationOperations |= BURN_REGISTRATION_ACTION_OPERATIONS_UPDATE_SIZE;
550
551 if (BOOTSTRAPPER_ACTION_UNINSTALL == pPlan->action) 544 if (BOOTSTRAPPER_ACTION_UNINSTALL == pPlan->action)
552 { 545 {
553 // If our provider key was detected and it points to our current bundle then we can 546 // If our provider key was not owned by a different bundle,
554 // unregister the bundle dependency. 547 // then plan to write our provider key registration to "fix it" if broken
555 if (pRegistration->sczDetectedProviderKeyBundleId && 548 // in case the bundle isn't successfully uninstalled.
556 CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, pRegistration->sczId, -1, pRegistration->sczDetectedProviderKeyBundleId, -1)) 549 if (!pRegistration->fDetectedForeignProviderKeyBundleId)
557 { 550 {
558 pPlan->dependencyRegistrationAction = BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER; 551 pPlan->dwRegistrationOperations |= BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_PROVIDER_KEY;
559 }
560 else // log that another bundle already owned our registration, hopefully this only happens when a newer version
561 { // of a bundle installed and is in the process of upgrading us.
562 LogId(REPORT_STANDARD, MSG_PLAN_SKIPPED_PROVIDER_KEY_REMOVAL, pRegistration->sczProviderKey, pRegistration->sczDetectedProviderKeyBundleId);
563 } 552 }
564 553
565 // Create the dictionary of dependents that should be ignored. 554 // Create the dictionary of dependents that should be ignored.
@@ -651,7 +640,7 @@ extern "C" HRESULT PlanRegistration(
651 640
652 // Always plan to write our provider key registration when installing/modify/repair to "fix it" 641 // Always plan to write our provider key registration when installing/modify/repair to "fix it"
653 // if broken. 642 // if broken.
654 pPlan->dependencyRegistrationAction = BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER; 643 pPlan->dwRegistrationOperations |= BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_PROVIDER_KEY;
655 644
656 // Create the dictionary of bundle dependents. 645 // Create the dictionary of bundle dependents.
657 hr = DictCreateStringList(&sdBundleDependents, 5, DICT_FLAG_CASEINSENSITIVE); 646 hr = DictCreateStringList(&sdBundleDependents, 5, DICT_FLAG_CASEINSENSITIVE);
diff --git a/src/burn/engine/plan.h b/src/burn/engine/plan.h
index 9bf72828..15092210 100644
--- a/src/burn/engine/plan.h
+++ b/src/burn/engine/plan.h
@@ -15,15 +15,7 @@ enum BURN_REGISTRATION_ACTION_OPERATIONS
15{ 15{
16 BURN_REGISTRATION_ACTION_OPERATIONS_NONE = 0x0, 16 BURN_REGISTRATION_ACTION_OPERATIONS_NONE = 0x0,
17 BURN_REGISTRATION_ACTION_OPERATIONS_CACHE_BUNDLE = 0x1, 17 BURN_REGISTRATION_ACTION_OPERATIONS_CACHE_BUNDLE = 0x1,
18 BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION = 0x2, 18 BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_PROVIDER_KEY = 0x2,
19 BURN_REGISTRATION_ACTION_OPERATIONS_UPDATE_SIZE = 0x4,
20};
21
22enum BURN_DEPENDENCY_REGISTRATION_ACTION
23{
24 BURN_DEPENDENCY_REGISTRATION_ACTION_NONE,
25 BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER,
26 BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER,
27}; 19};
28 20
29enum BURN_DEPENDENT_REGISTRATION_ACTION_TYPE 21enum BURN_DEPENDENT_REGISTRATION_ACTION_TYPE
@@ -272,8 +264,6 @@ typedef struct _BURN_PLAN
272 BOOL fEnabledForwardCompatibleBundle; 264 BOOL fEnabledForwardCompatibleBundle;
273 BURN_PACKAGE forwardCompatibleBundle; 265 BURN_PACKAGE forwardCompatibleBundle;
274 266
275 BURN_DEPENDENCY_REGISTRATION_ACTION dependencyRegistrationAction;
276
277 BURN_DEPENDENT_REGISTRATION_ACTION* rgRegistrationActions; 267 BURN_DEPENDENT_REGISTRATION_ACTION* rgRegistrationActions;
278 DWORD cRegistrationActions; 268 DWORD cRegistrationActions;
279 269
diff --git a/src/burn/engine/registration.cpp b/src/burn/engine/registration.cpp
index c76dde53..59947867 100644
--- a/src/burn/engine/registration.cpp
+++ b/src/burn/engine/registration.cpp
@@ -605,7 +605,6 @@ extern "C" HRESULT RegistrationSessionBegin(
605 __in BURN_CACHE* pCache, 605 __in BURN_CACHE* pCache,
606 __in BURN_VARIABLES* pVariables, 606 __in BURN_VARIABLES* pVariables,
607 __in DWORD dwRegistrationOptions, 607 __in DWORD dwRegistrationOptions,
608 __in BURN_DEPENDENCY_REGISTRATION_ACTION dependencyRegistrationAction,
609 __in DWORD64 qwEstimatedSize, 608 __in DWORD64 qwEstimatedSize,
610 __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType 609 __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType
611 ) 610 )
@@ -635,206 +634,199 @@ extern "C" HRESULT RegistrationSessionBegin(
635 ExitOnFailure(hr, "Failed to create registration key."); 634 ExitOnFailure(hr, "Failed to create registration key.");
636 635
637 // Write any ARP values and software tags. 636 // Write any ARP values and software tags.
638 if (dwRegistrationOptions & BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION) 637 hr = RegWriteString(hkRegistration, BURN_REGISTRATION_REGISTRY_BUNDLE_CACHE_PATH, pRegistration->sczCacheExecutablePath);
639 { 638 ExitOnFailure(hr, "Failed to write %ls value.", BURN_REGISTRATION_REGISTRY_BUNDLE_CACHE_PATH);
640 // Upgrade information
641 hr = RegWriteString(hkRegistration, BURN_REGISTRATION_REGISTRY_BUNDLE_CACHE_PATH, pRegistration->sczCacheExecutablePath);
642 ExitOnFailure(hr, "Failed to write %ls value.", BURN_REGISTRATION_REGISTRY_BUNDLE_CACHE_PATH);
643 639
644 hr = RegWriteStringArray(hkRegistration, BURN_REGISTRATION_REGISTRY_BUNDLE_UPGRADE_CODE, pRegistration->rgsczUpgradeCodes, pRegistration->cUpgradeCodes); 640 hr = RegWriteStringArray(hkRegistration, BURN_REGISTRATION_REGISTRY_BUNDLE_UPGRADE_CODE, pRegistration->rgsczUpgradeCodes, pRegistration->cUpgradeCodes);
645 ExitOnFailure(hr, "Failed to write %ls value.", BURN_REGISTRATION_REGISTRY_BUNDLE_UPGRADE_CODE); 641 ExitOnFailure(hr, "Failed to write %ls value.", BURN_REGISTRATION_REGISTRY_BUNDLE_UPGRADE_CODE);
646 642
647 hr = RegWriteStringArray(hkRegistration, BURN_REGISTRATION_REGISTRY_BUNDLE_ADDON_CODE, pRegistration->rgsczAddonCodes, pRegistration->cAddonCodes); 643 hr = RegWriteStringArray(hkRegistration, BURN_REGISTRATION_REGISTRY_BUNDLE_ADDON_CODE, pRegistration->rgsczAddonCodes, pRegistration->cAddonCodes);
648 ExitOnFailure(hr, "Failed to write %ls value.", BURN_REGISTRATION_REGISTRY_BUNDLE_ADDON_CODE); 644 ExitOnFailure(hr, "Failed to write %ls value.", BURN_REGISTRATION_REGISTRY_BUNDLE_ADDON_CODE);
649 645
650 hr = RegWriteStringArray(hkRegistration, BURN_REGISTRATION_REGISTRY_BUNDLE_DETECT_CODE, pRegistration->rgsczDetectCodes, pRegistration->cDetectCodes); 646 hr = RegWriteStringArray(hkRegistration, BURN_REGISTRATION_REGISTRY_BUNDLE_DETECT_CODE, pRegistration->rgsczDetectCodes, pRegistration->cDetectCodes);
651 ExitOnFailure(hr, "Failed to write %ls value.", BURN_REGISTRATION_REGISTRY_BUNDLE_DETECT_CODE); 647 ExitOnFailure(hr, "Failed to write %ls value.", BURN_REGISTRATION_REGISTRY_BUNDLE_DETECT_CODE);
652 648
653 hr = RegWriteStringArray(hkRegistration, BURN_REGISTRATION_REGISTRY_BUNDLE_PATCH_CODE, pRegistration->rgsczPatchCodes, pRegistration->cPatchCodes); 649 hr = RegWriteStringArray(hkRegistration, BURN_REGISTRATION_REGISTRY_BUNDLE_PATCH_CODE, pRegistration->rgsczPatchCodes, pRegistration->cPatchCodes);
654 ExitOnFailure(hr, "Failed to write %ls value.", BURN_REGISTRATION_REGISTRY_BUNDLE_PATCH_CODE); 650 ExitOnFailure(hr, "Failed to write %ls value.", BURN_REGISTRATION_REGISTRY_BUNDLE_PATCH_CODE);
655 651
656 hr = RegWriteString(hkRegistration, BURN_REGISTRATION_REGISTRY_BUNDLE_VERSION, pRegistration->pVersion->sczVersion); 652 hr = RegWriteString(hkRegistration, BURN_REGISTRATION_REGISTRY_BUNDLE_VERSION, pRegistration->pVersion->sczVersion);
657 ExitOnFailure(hr, "Failed to write %ls value.", BURN_REGISTRATION_REGISTRY_BUNDLE_VERSION); 653 ExitOnFailure(hr, "Failed to write %ls value.", BURN_REGISTRATION_REGISTRY_BUNDLE_VERSION);
658 654
659 hr = RegWriteNumber(hkRegistration, REGISTRY_BUNDLE_VERSION_MAJOR, pRegistration->pVersion->dwMajor); 655 hr = RegWriteNumber(hkRegistration, REGISTRY_BUNDLE_VERSION_MAJOR, pRegistration->pVersion->dwMajor);
660 ExitOnFailure(hr, "Failed to write %ls value.", REGISTRY_BUNDLE_VERSION_MAJOR); 656 ExitOnFailure(hr, "Failed to write %ls value.", REGISTRY_BUNDLE_VERSION_MAJOR);
661 657
662 hr = RegWriteNumber(hkRegistration, REGISTRY_BUNDLE_VERSION_MINOR, pRegistration->pVersion->dwMinor); 658 hr = RegWriteNumber(hkRegistration, REGISTRY_BUNDLE_VERSION_MINOR, pRegistration->pVersion->dwMinor);
663 ExitOnFailure(hr, "Failed to write %ls value.", REGISTRY_BUNDLE_VERSION_MINOR); 659 ExitOnFailure(hr, "Failed to write %ls value.", REGISTRY_BUNDLE_VERSION_MINOR);
664 660
665 if (pRegistration->sczProviderKey) 661 if (pRegistration->sczProviderKey)
666 { 662 {
667 hr = RegWriteString(hkRegistration, BURN_REGISTRATION_REGISTRY_BUNDLE_PROVIDER_KEY, pRegistration->sczProviderKey); 663 hr = RegWriteString(hkRegistration, BURN_REGISTRATION_REGISTRY_BUNDLE_PROVIDER_KEY, pRegistration->sczProviderKey);
668 ExitOnFailure(hr, "Failed to write %ls value.", BURN_REGISTRATION_REGISTRY_BUNDLE_PROVIDER_KEY); 664 ExitOnFailure(hr, "Failed to write %ls value.", BURN_REGISTRATION_REGISTRY_BUNDLE_PROVIDER_KEY);
669 } 665 }
670 666
671 if (pRegistration->sczTag) 667 if (pRegistration->sczTag)
672 { 668 {
673 hr = RegWriteString(hkRegistration, BURN_REGISTRATION_REGISTRY_BUNDLE_TAG, pRegistration->sczTag); 669 hr = RegWriteString(hkRegistration, BURN_REGISTRATION_REGISTRY_BUNDLE_TAG, pRegistration->sczTag);
674 ExitOnFailure(hr, "Failed to write %ls value.", BURN_REGISTRATION_REGISTRY_BUNDLE_TAG); 670 ExitOnFailure(hr, "Failed to write %ls value.", BURN_REGISTRATION_REGISTRY_BUNDLE_TAG);
675 } 671 }
676 672
677 hr = RegWriteStringFormatted(hkRegistration, BURN_REGISTRATION_REGISTRY_ENGINE_VERSION, L"%hs", szVerMajorMinorBuild); 673 hr = RegWriteStringFormatted(hkRegistration, BURN_REGISTRATION_REGISTRY_ENGINE_VERSION, L"%hs", szVerMajorMinorBuild);
678 ExitOnFailure(hr, "Failed to write %ls value.", BURN_REGISTRATION_REGISTRY_ENGINE_VERSION); 674 ExitOnFailure(hr, "Failed to write %ls value.", BURN_REGISTRATION_REGISTRY_ENGINE_VERSION);
679 675
680 hr = RegWriteNumber(hkRegistration, BURN_REGISTRATION_REGISTRY_ENGINE_PROTOCOL_VERSION, BURN_PROTOCOL_VERSION); 676 hr = RegWriteNumber(hkRegistration, BURN_REGISTRATION_REGISTRY_ENGINE_PROTOCOL_VERSION, BURN_PROTOCOL_VERSION);
681 ExitOnFailure(hr, "Failed to write %ls value.", BURN_REGISTRATION_REGISTRY_ENGINE_PROTOCOL_VERSION); 677 ExitOnFailure(hr, "Failed to write %ls value.", BURN_REGISTRATION_REGISTRY_ENGINE_PROTOCOL_VERSION);
682 678
683 // DisplayIcon: [path to exe] and ",0" to refer to the first icon in the executable. 679 // DisplayIcon: [path to exe] and ",0" to refer to the first icon in the executable.
684 hr = RegWriteStringFormatted(hkRegistration, REGISTRY_BUNDLE_DISPLAY_ICON, L"%s,0", pRegistration->sczCacheExecutablePath); 680 hr = RegWriteStringFormatted(hkRegistration, REGISTRY_BUNDLE_DISPLAY_ICON, L"%s,0", pRegistration->sczCacheExecutablePath);
685 ExitOnFailure(hr, "Failed to write %ls value.", REGISTRY_BUNDLE_DISPLAY_ICON); 681 ExitOnFailure(hr, "Failed to write %ls value.", REGISTRY_BUNDLE_DISPLAY_ICON);
686 682
687 // update display name 683 // update display name
688 hr = UpdateBundleNameRegistration(pRegistration, pVariables, hkRegistration, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS == registrationType); 684 hr = UpdateBundleNameRegistration(pRegistration, pVariables, hkRegistration, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS == registrationType);
689 ExitOnFailure(hr, "Failed to update name and publisher."); 685 ExitOnFailure(hr, "Failed to update name and publisher.");
690 686
691 // DisplayVersion: provided by UI 687 // DisplayVersion: provided by UI
692 if (pRegistration->sczDisplayVersion) 688 if (pRegistration->sczDisplayVersion)
693 { 689 {
694 hr = RegWriteString(hkRegistration, REGISTRY_BUNDLE_DISPLAY_VERSION, pRegistration->sczDisplayVersion); 690 hr = RegWriteString(hkRegistration, REGISTRY_BUNDLE_DISPLAY_VERSION, pRegistration->sczDisplayVersion);
695 ExitOnFailure(hr, "Failed to write %ls value.", REGISTRY_BUNDLE_DISPLAY_VERSION); 691 ExitOnFailure(hr, "Failed to write %ls value.", REGISTRY_BUNDLE_DISPLAY_VERSION);
696 } 692 }
697 693
698 // Publisher: provided by UI 694 // Publisher: provided by UI
699 hr = GetBundleManufacturer(pRegistration, pVariables, &sczPublisher); 695 hr = GetBundleManufacturer(pRegistration, pVariables, &sczPublisher);
700 hr = RegWriteString(hkRegistration, REGISTRY_BUNDLE_PUBLISHER, SUCCEEDED(hr) ? sczPublisher : pRegistration->sczPublisher); 696 hr = RegWriteString(hkRegistration, REGISTRY_BUNDLE_PUBLISHER, SUCCEEDED(hr) ? sczPublisher : pRegistration->sczPublisher);
701 ExitOnFailure(hr, "Failed to write %ls value.", REGISTRY_BUNDLE_PUBLISHER); 697 ExitOnFailure(hr, "Failed to write %ls value.", REGISTRY_BUNDLE_PUBLISHER);
702 698
703 // HelpLink: provided by UI 699 // HelpLink: provided by UI
704 if (pRegistration->sczHelpLink) 700 if (pRegistration->sczHelpLink)
705 { 701 {
706 hr = RegWriteString(hkRegistration, REGISTRY_BUNDLE_HELP_LINK, pRegistration->sczHelpLink); 702 hr = RegWriteString(hkRegistration, REGISTRY_BUNDLE_HELP_LINK, pRegistration->sczHelpLink);
707 ExitOnFailure(hr, "Failed to write %ls value.", REGISTRY_BUNDLE_HELP_LINK); 703 ExitOnFailure(hr, "Failed to write %ls value.", REGISTRY_BUNDLE_HELP_LINK);
708 } 704 }
709 705
710 // HelpTelephone: provided by UI 706 // HelpTelephone: provided by UI
711 if (pRegistration->sczHelpTelephone) 707 if (pRegistration->sczHelpTelephone)
712 { 708 {
713 hr = RegWriteString(hkRegistration, REGISTRY_BUNDLE_HELP_TELEPHONE, pRegistration->sczHelpTelephone); 709 hr = RegWriteString(hkRegistration, REGISTRY_BUNDLE_HELP_TELEPHONE, pRegistration->sczHelpTelephone);
714 ExitOnFailure(hr, "Failed to write %ls value.", REGISTRY_BUNDLE_HELP_TELEPHONE); 710 ExitOnFailure(hr, "Failed to write %ls value.", REGISTRY_BUNDLE_HELP_TELEPHONE);
715 } 711 }
716 712
717 // URLInfoAbout, provided by UI 713 // URLInfoAbout, provided by UI
718 if (pRegistration->sczAboutUrl) 714 if (pRegistration->sczAboutUrl)
719 { 715 {
720 hr = RegWriteString(hkRegistration, REGISTRY_BUNDLE_URL_INFO_ABOUT, pRegistration->sczAboutUrl); 716 hr = RegWriteString(hkRegistration, REGISTRY_BUNDLE_URL_INFO_ABOUT, pRegistration->sczAboutUrl);
721 ExitOnFailure(hr, "Failed to write %ls value.", REGISTRY_BUNDLE_URL_INFO_ABOUT); 717 ExitOnFailure(hr, "Failed to write %ls value.", REGISTRY_BUNDLE_URL_INFO_ABOUT);
722 } 718 }
723 719
724 // URLUpdateInfo, provided by UI 720 // URLUpdateInfo, provided by UI
725 if (pRegistration->sczUpdateUrl) 721 if (pRegistration->sczUpdateUrl)
726 { 722 {
727 hr = RegWriteString(hkRegistration, REGISTRY_BUNDLE_URL_UPDATE_INFO, pRegistration->sczUpdateUrl); 723 hr = RegWriteString(hkRegistration, REGISTRY_BUNDLE_URL_UPDATE_INFO, pRegistration->sczUpdateUrl);
728 ExitOnFailure(hr, "Failed to write %ls value.", REGISTRY_BUNDLE_URL_UPDATE_INFO); 724 ExitOnFailure(hr, "Failed to write %ls value.", REGISTRY_BUNDLE_URL_UPDATE_INFO);
729 } 725 }
730 726
731 // ParentDisplayName 727 // ParentDisplayName
732 if (pRegistration->sczParentDisplayName) 728 if (pRegistration->sczParentDisplayName)
733 { 729 {
734 hr = RegWriteString(hkRegistration, REGISTRY_BUNDLE_PARENT_DISPLAY_NAME, pRegistration->sczParentDisplayName); 730 hr = RegWriteString(hkRegistration, REGISTRY_BUNDLE_PARENT_DISPLAY_NAME, pRegistration->sczParentDisplayName);
735 ExitOnFailure(hr, "Failed to write %ls value.", REGISTRY_BUNDLE_PARENT_DISPLAY_NAME); 731 ExitOnFailure(hr, "Failed to write %ls value.", REGISTRY_BUNDLE_PARENT_DISPLAY_NAME);
736 732
737 // Need to write the ParentKeyName but can be set to anything. 733 // Need to write the ParentKeyName but can be set to anything.
738 hr = RegWriteString(hkRegistration, REGISTRY_BUNDLE_PARENT_KEY_NAME, pRegistration->sczParentDisplayName); 734 hr = RegWriteString(hkRegistration, REGISTRY_BUNDLE_PARENT_KEY_NAME, pRegistration->sczParentDisplayName);
739 ExitOnFailure(hr, "Failed to write %ls value.", REGISTRY_BUNDLE_PARENT_KEY_NAME); 735 ExitOnFailure(hr, "Failed to write %ls value.", REGISTRY_BUNDLE_PARENT_KEY_NAME);
740 } 736 }
741 737
742 // Comments, provided by UI 738 // Comments, provided by UI
743 if (pRegistration->sczComments) 739 if (pRegistration->sczComments)
744 { 740 {
745 hr = RegWriteString(hkRegistration, REGISTRY_BUNDLE_COMMENTS, pRegistration->sczComments); 741 hr = RegWriteString(hkRegistration, REGISTRY_BUNDLE_COMMENTS, pRegistration->sczComments);
746 ExitOnFailure(hr, "Failed to write %ls value.", REGISTRY_BUNDLE_COMMENTS); 742 ExitOnFailure(hr, "Failed to write %ls value.", REGISTRY_BUNDLE_COMMENTS);
747 } 743 }
748 744
749 // Contact, provided by UI 745 // Contact, provided by UI
750 if (pRegistration->sczContact) 746 if (pRegistration->sczContact)
751 { 747 {
752 hr = RegWriteString(hkRegistration, REGISTRY_BUNDLE_CONTACT, pRegistration->sczContact); 748 hr = RegWriteString(hkRegistration, REGISTRY_BUNDLE_CONTACT, pRegistration->sczContact);
753 ExitOnFailure(hr, "Failed to write %ls value.", REGISTRY_BUNDLE_CONTACT); 749 ExitOnFailure(hr, "Failed to write %ls value.", REGISTRY_BUNDLE_CONTACT);
754 } 750 }
755 751
756 // InstallLocation: provided by UI 752 // InstallLocation: provided by UI
757 // TODO: need to figure out what "InstallLocation" means in a chainer. <smile/> 753 // TODO: need to figure out what "InstallLocation" means in a chainer. <smile/>
758 754
759 // NoModify 755 // NoModify
760 if (BURN_REGISTRATION_MODIFY_DISABLE == pRegistration->modify) 756 if (BURN_REGISTRATION_MODIFY_DISABLE == pRegistration->modify)
761 { 757 {
762 hr = RegWriteNumber(hkRegistration, REGISTRY_BUNDLE_NO_MODIFY, 1); 758 hr = RegWriteNumber(hkRegistration, REGISTRY_BUNDLE_NO_MODIFY, 1);
763 ExitOnFailure(hr, "Failed to write %ls value.", REGISTRY_BUNDLE_NO_MODIFY); 759 ExitOnFailure(hr, "Failed to write %ls value.", REGISTRY_BUNDLE_NO_MODIFY);
764 } 760 }
765 else if (BURN_REGISTRATION_MODIFY_DISABLE_BUTTON != pRegistration->modify) // if support modify (aka: did not disable anything) 761 else if (BURN_REGISTRATION_MODIFY_DISABLE_BUTTON != pRegistration->modify) // if support modify (aka: did not disable anything)
766 { 762 {
767 // ModifyPath: [path to exe] /modify 763 // ModifyPath: [path to exe] /modify
768 hr = RegWriteStringFormatted(hkRegistration, REGISTRY_BUNDLE_MODIFY_PATH, L"\"%ls\" /%ls /modify", pRegistration->sczCacheExecutablePath, BURN_COMMANDLINE_SWITCH_CLEAN_ROOM); 764 hr = RegWriteStringFormatted(hkRegistration, REGISTRY_BUNDLE_MODIFY_PATH, L"\"%ls\" /%ls /modify", pRegistration->sczCacheExecutablePath, BURN_COMMANDLINE_SWITCH_CLEAN_ROOM);
769 ExitOnFailure(hr, "Failed to write %ls value.", REGISTRY_BUNDLE_MODIFY_PATH); 765 ExitOnFailure(hr, "Failed to write %ls value.", REGISTRY_BUNDLE_MODIFY_PATH);
770 766
771 // NoElevateOnModify: 1 767 // NoElevateOnModify: 1
772 hr = RegWriteNumber(hkRegistration, REGISTRY_BUNDLE_NO_ELEVATE_ON_MODIFY, 1); 768 hr = RegWriteNumber(hkRegistration, REGISTRY_BUNDLE_NO_ELEVATE_ON_MODIFY, 1);
773 ExitOnFailure(hr, "Failed to write %ls value.", REGISTRY_BUNDLE_NO_ELEVATE_ON_MODIFY); 769 ExitOnFailure(hr, "Failed to write %ls value.", REGISTRY_BUNDLE_NO_ELEVATE_ON_MODIFY);
774 } 770 }
775 771
776 // NoRemove: should this be allowed? 772 // NoRemove: should this be allowed?
777 if (pRegistration->fNoRemoveDefined) 773 if (pRegistration->fNoRemoveDefined)
778 { 774 {
779 hr = RegWriteNumber(hkRegistration, REGISTRY_BUNDLE_NO_REMOVE, (DWORD)pRegistration->fNoRemove); 775 hr = RegWriteNumber(hkRegistration, REGISTRY_BUNDLE_NO_REMOVE, (DWORD)pRegistration->fNoRemove);
780 ExitOnFailure(hr, "Failed to write %ls value.", REGISTRY_BUNDLE_NO_REMOVE); 776 ExitOnFailure(hr, "Failed to write %ls value.", REGISTRY_BUNDLE_NO_REMOVE);
781 } 777 }
782 778
783 // Conditionally hide the ARP entry. 779 // Conditionally hide the ARP entry.
784 if (!pRegistration->fRegisterArp) 780 if (!pRegistration->fRegisterArp)
785 { 781 {
786 hr = RegWriteNumber(hkRegistration, REGISTRY_BUNDLE_SYSTEM_COMPONENT, 1); 782 hr = RegWriteNumber(hkRegistration, REGISTRY_BUNDLE_SYSTEM_COMPONENT, 1);
787 ExitOnFailure(hr, "Failed to write %ls value.", REGISTRY_BUNDLE_SYSTEM_COMPONENT); 783 ExitOnFailure(hr, "Failed to write %ls value.", REGISTRY_BUNDLE_SYSTEM_COMPONENT);
788 } 784 }
789 785
790 // QuietUninstallString: [path to exe] /uninstall /quiet 786 // QuietUninstallString: [path to exe] /uninstall /quiet
791 hr = RegWriteStringFormatted(hkRegistration, REGISTRY_BUNDLE_QUIET_UNINSTALL_STRING, L"\"%ls\" /%ls /uninstall /quiet", pRegistration->sczCacheExecutablePath, BURN_COMMANDLINE_SWITCH_CLEAN_ROOM); 787 hr = RegWriteStringFormatted(hkRegistration, REGISTRY_BUNDLE_QUIET_UNINSTALL_STRING, L"\"%ls\" /%ls /uninstall /quiet", pRegistration->sczCacheExecutablePath, BURN_COMMANDLINE_SWITCH_CLEAN_ROOM);
792 ExitOnFailure(hr, "Failed to write %ls value.", REGISTRY_BUNDLE_QUIET_UNINSTALL_STRING); 788 ExitOnFailure(hr, "Failed to write %ls value.", REGISTRY_BUNDLE_QUIET_UNINSTALL_STRING);
793 789
794 // UninstallString, [path to exe] 790 // UninstallString, [path to exe]
795 // If the modify button is to be disabled, we'll add "/modify" to the uninstall string because the button is "Uninstall/Change". Otherwise, 791 // If the modify button is to be disabled, we'll add "/modify" to the uninstall string because the button is "Uninstall/Change". Otherwise,
796 // it's just the "Uninstall" button so we add "/uninstall" to make the program just go away. 792 // it's just the "Uninstall" button so we add "/uninstall" to make the program just go away.
797 LPCWSTR wzUninstallParameters = (BURN_REGISTRATION_MODIFY_DISABLE_BUTTON == pRegistration->modify) ? L"/modify" : L" /uninstall"; 793 LPCWSTR wzUninstallParameters = (BURN_REGISTRATION_MODIFY_DISABLE_BUTTON == pRegistration->modify) ? L"/modify" : L" /uninstall";
798 hr = RegWriteStringFormatted(hkRegistration, REGISTRY_BUNDLE_UNINSTALL_STRING, L"\"%ls\" /%ls %ls", pRegistration->sczCacheExecutablePath, BURN_COMMANDLINE_SWITCH_CLEAN_ROOM, wzUninstallParameters); 794 hr = RegWriteStringFormatted(hkRegistration, REGISTRY_BUNDLE_UNINSTALL_STRING, L"\"%ls\" /%ls %ls", pRegistration->sczCacheExecutablePath, BURN_COMMANDLINE_SWITCH_CLEAN_ROOM, wzUninstallParameters);
799 ExitOnFailure(hr, "Failed to write %ls value.", REGISTRY_BUNDLE_UNINSTALL_STRING); 795 ExitOnFailure(hr, "Failed to write %ls value.", REGISTRY_BUNDLE_UNINSTALL_STRING);
800 796
801 if (pRegistration->softwareTags.cSoftwareTags) 797 if (pRegistration->softwareTags.cSoftwareTags)
802 { 798 {
803 hr = WriteSoftwareTags(pVariables, &pRegistration->softwareTags); 799 hr = WriteSoftwareTags(pVariables, &pRegistration->softwareTags);
804 ExitOnFailure(hr, "Failed to write software tags."); 800 ExitOnFailure(hr, "Failed to write software tags.");
805 } 801 }
806 802
807 // Update registration. 803 // Update registration.
808 if (pRegistration->update.fRegisterUpdate) 804 if (pRegistration->update.fRegisterUpdate)
809 { 805 {
810 hr = WriteUpdateRegistration(pRegistration, pVariables); 806 hr = WriteUpdateRegistration(pRegistration, pVariables);
811 ExitOnFailure(hr, "Failed to write update registration."); 807 ExitOnFailure(hr, "Failed to write update registration.");
812 }
813 } 808 }
814 809
815 // Update estimated size. 810 // Update estimated size.
816 if (dwRegistrationOptions & BURN_REGISTRATION_ACTION_OPERATIONS_UPDATE_SIZE) 811 qwEstimatedSize /= 1024; // Convert bytes to KB
812 if (0 < qwEstimatedSize)
817 { 813 {
818 qwEstimatedSize /= 1024; // Convert bytes to KB 814 if (DWORD_MAX < qwEstimatedSize)
819 if (0 < qwEstimatedSize)
820 { 815 {
821 if (DWORD_MAX < qwEstimatedSize) 816 // ARP doesn't support QWORDs here
822 { 817 dwSize = DWORD_MAX;
823 // ARP doesn't support QWORDs here
824 dwSize = DWORD_MAX;
825 }
826 else
827 {
828 dwSize = static_cast<DWORD>(qwEstimatedSize);
829 }
830
831 hr = RegWriteNumber(hkRegistration, REGISTRY_BUNDLE_ESTIMATED_SIZE, dwSize);
832 ExitOnFailure(hr, "Failed to write %ls value.", REGISTRY_BUNDLE_ESTIMATED_SIZE);
833 } 818 }
819 else
820 {
821 dwSize = static_cast<DWORD>(qwEstimatedSize);
822 }
823
824 hr = RegWriteNumber(hkRegistration, REGISTRY_BUNDLE_ESTIMATED_SIZE, dwSize);
825 ExitOnFailure(hr, "Failed to write %ls value.", REGISTRY_BUNDLE_ESTIMATED_SIZE);
834 } 826 }
835 827
836 // Register the bundle dependency key. 828 // Register the bundle dependency key.
837 if (BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER == dependencyRegistrationAction) 829 if (dwRegistrationOptions & BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_PROVIDER_KEY)
838 { 830 {
839 hr = DependencyRegisterBundle(pRegistration); 831 hr = DependencyRegisterBundle(pRegistration);
840 ExitOnFailure(hr, "Failed to register the bundle dependency key."); 832 ExitOnFailure(hr, "Failed to register the bundle dependency key.");
@@ -897,7 +889,6 @@ extern "C" HRESULT RegistrationSessionEnd(
897 __in BURN_PACKAGES* pPackages, 889 __in BURN_PACKAGES* pPackages,
898 __in BURN_RESUME_MODE resumeMode, 890 __in BURN_RESUME_MODE resumeMode,
899 __in BOOTSTRAPPER_APPLY_RESTART restart, 891 __in BOOTSTRAPPER_APPLY_RESTART restart,
900 __in BURN_DEPENDENCY_REGISTRATION_ACTION dependencyRegistrationAction,
901 __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType 892 __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType
902 ) 893 )
903{ 894{
@@ -909,11 +900,8 @@ extern "C" HRESULT RegistrationSessionEnd(
909 { 900 {
910 AssertSz(BOOTSTRAPPER_REGISTRATION_TYPE_NONE == registrationType, "Registration type must be NONE if resume mode is NONE"); 901 AssertSz(BOOTSTRAPPER_REGISTRATION_TYPE_NONE == registrationType, "Registration type must be NONE if resume mode is NONE");
911 902
912 // If we just registered the bundle dependency but something went wrong and caused us to not 903 // If we own the bundle dependency then remove it.
913 // keep the bundle registration (like rollback) or we are supposed to unregister the bundle 904 if (!pRegistration->fDetectedForeignProviderKeyBundleId)
914 // dependency when unregistering the bundle, do so.
915 if (BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER == dependencyRegistrationAction ||
916 BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER == dependencyRegistrationAction)
917 { 905 {
918 // Remove the bundle dependency key. 906 // Remove the bundle dependency key.
919 DependencyUnregisterBundle(pRegistration, pPackages); 907 DependencyUnregisterBundle(pRegistration, pPackages);
diff --git a/src/burn/engine/registration.h b/src/burn/engine/registration.h
index e33d5270..0ae61974 100644
--- a/src/burn/engine/registration.h
+++ b/src/burn/engine/registration.h
@@ -7,11 +7,6 @@ extern "C" {
7#endif 7#endif
8 8
9 9
10enum BURN_MODE;
11enum BURN_DEPENDENCY_REGISTRATION_ACTION;
12struct _BURN_LOGGING;
13typedef _BURN_LOGGING BURN_LOGGING;
14
15// constants 10// constants
16 11
17const LPCWSTR BURN_REGISTRATION_REGISTRY_UNINSTALL_KEY = L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall"; 12const LPCWSTR BURN_REGISTRATION_REGISTRY_UNINSTALL_KEY = L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
@@ -152,6 +147,7 @@ typedef struct _BURN_REGISTRATION
152 BOOL fForwardCompatibleBundleExists; // Only valid after detect. 147 BOOL fForwardCompatibleBundleExists; // Only valid after detect.
153 BOOL fEligibleForCleanup; // Only valid after detect. 148 BOOL fEligibleForCleanup; // Only valid after detect.
154 149
150 BOOL fDetectedForeignProviderKeyBundleId;
155 LPWSTR sczDetectedProviderKeyBundleId; 151 LPWSTR sczDetectedProviderKeyBundleId;
156 LPWSTR sczBundlePackageAncestors; 152 LPWSTR sczBundlePackageAncestors;
157} BURN_REGISTRATION; 153} BURN_REGISTRATION;
@@ -187,7 +183,6 @@ HRESULT RegistrationSessionBegin(
187 __in BURN_CACHE* pCache, 183 __in BURN_CACHE* pCache,
188 __in BURN_VARIABLES* pVariables, 184 __in BURN_VARIABLES* pVariables,
189 __in DWORD dwRegistrationOptions, 185 __in DWORD dwRegistrationOptions,
190 __in BURN_DEPENDENCY_REGISTRATION_ACTION dependencyRegistrationAction,
191 __in DWORD64 qwEstimatedSize, 186 __in DWORD64 qwEstimatedSize,
192 __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType 187 __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType
193 ); 188 );
@@ -203,7 +198,6 @@ HRESULT RegistrationSessionEnd(
203 __in BURN_PACKAGES* pPackages, 198 __in BURN_PACKAGES* pPackages,
204 __in BURN_RESUME_MODE resumeMode, 199 __in BURN_RESUME_MODE resumeMode,
205 __in BOOTSTRAPPER_APPLY_RESTART restart, 200 __in BOOTSTRAPPER_APPLY_RESTART restart,
206 __in BURN_DEPENDENCY_REGISTRATION_ACTION dependencyRegistrationAction,
207 __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType 201 __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType
208 ); 202 );
209HRESULT RegistrationSaveState( 203HRESULT RegistrationSaveState(
diff --git a/src/burn/test/BurnUnitTest/RegistrationTest.cpp b/src/burn/test/BurnUnitTest/RegistrationTest.cpp
index d2ec0a82..2ebab277 100644
--- a/src/burn/test/BurnUnitTest/RegistrationTest.cpp
+++ b/src/burn/test/BurnUnitTest/RegistrationTest.cpp
@@ -79,6 +79,7 @@ namespace Bootstrapper
79 BURN_CACHE cache = { }; 79 BURN_CACHE cache = { };
80 BURN_ENGINE_COMMAND internalCommand = { }; 80 BURN_ENGINE_COMMAND internalCommand = { };
81 String^ cacheDirectory = Path::Combine(Path::Combine(Environment::GetFolderPath(Environment::SpecialFolder::LocalApplicationData), gcnew String(L"Package Cache")), gcnew String(TEST_BUNDLE_ID)); 81 String^ cacheDirectory = Path::Combine(Path::Combine(Environment::GetFolderPath(Environment::SpecialFolder::LocalApplicationData), gcnew String(L"Package Cache")), gcnew String(TEST_BUNDLE_ID));
82 DWORD dwRegistrationOptions = BURN_REGISTRATION_ACTION_OPERATIONS_CACHE_BUNDLE;
82 83
83 try 84 try
84 { 85 {
@@ -125,7 +126,7 @@ namespace Bootstrapper
125 TestThrowOnFailure(hr, L"Failed to get current process path."); 126 TestThrowOnFailure(hr, L"Failed to get current process path.");
126 127
127 // write registration 128 // write registration
128 hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &cache, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_CACHE_BUNDLE | BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, 0, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS); 129 hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &cache, &variables, dwRegistrationOptions, 0, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS);
129 TestThrowOnFailure(hr, L"Failed to register bundle."); 130 TestThrowOnFailure(hr, L"Failed to register bundle.");
130 131
131 // verify that registration was created 132 // verify that registration was created
@@ -136,7 +137,7 @@ namespace Bootstrapper
136 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.clean.room /burn.runonce"), (String^)(Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr))); 137 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.clean.room /burn.runonce"), (String^)(Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr)));
137 138
138 // end session 139 // end session
139 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_NONE); 140 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BOOTSTRAPPER_REGISTRATION_TYPE_NONE);
140 TestThrowOnFailure(hr, L"Failed to unregister bundle."); 141 TestThrowOnFailure(hr, L"Failed to unregister bundle.");
141 142
142 // verify that registration was removed 143 // verify that registration was removed
@@ -179,6 +180,7 @@ namespace Bootstrapper
179 BURN_CACHE cache = { }; 180 BURN_CACHE cache = { };
180 BURN_ENGINE_COMMAND internalCommand = { }; 181 BURN_ENGINE_COMMAND internalCommand = { };
181 String^ cacheDirectory = Path::Combine(Path::Combine(Environment::GetFolderPath(Environment::SpecialFolder::LocalApplicationData), gcnew String(L"Package Cache")), gcnew String(TEST_BUNDLE_ID)); 182 String^ cacheDirectory = Path::Combine(Path::Combine(Environment::GetFolderPath(Environment::SpecialFolder::LocalApplicationData), gcnew String(L"Package Cache")), gcnew String(TEST_BUNDLE_ID));
183 DWORD dwRegistrationOptions = 0;
182 try 184 try
183 { 185 {
184 // set mock API's 186 // set mock API's
@@ -228,7 +230,7 @@ namespace Bootstrapper
228 // 230 //
229 231
230 // write registration 232 // write registration
231 hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &cache, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, 0, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS); 233 hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &cache, &variables, dwRegistrationOptions, 0, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS);
232 TestThrowOnFailure(hr, L"Failed to register bundle."); 234 TestThrowOnFailure(hr, L"Failed to register bundle.");
233 235
234 // verify that registration was created 236 // verify that registration was created
@@ -237,7 +239,7 @@ namespace Bootstrapper
237 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.clean.room /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr)); 239 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.clean.room /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr));
238 240
239 // complete registration 241 // complete registration
240 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_ARP, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS); 242 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_ARP, BOOTSTRAPPER_APPLY_RESTART_NONE, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS);
241 TestThrowOnFailure(hr, L"Failed to unregister bundle."); 243 TestThrowOnFailure(hr, L"Failed to unregister bundle.");
242 244
243 // verify that registration was updated 245 // verify that registration was updated
@@ -250,7 +252,7 @@ namespace Bootstrapper
250 // 252 //
251 253
252 // write registration 254 // write registration
253 hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &cache, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, 0, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS); 255 hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &cache, &variables, dwRegistrationOptions, 0, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS);
254 TestThrowOnFailure(hr, L"Failed to register bundle."); 256 TestThrowOnFailure(hr, L"Failed to register bundle.");
255 257
256 // verify that registration was updated 258 // verify that registration was updated
@@ -259,7 +261,7 @@ namespace Bootstrapper
259 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.clean.room /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr)); 261 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.clean.room /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr));
260 262
261 // delete registration 263 // delete registration
262 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_NONE); 264 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BOOTSTRAPPER_REGISTRATION_TYPE_NONE);
263 TestThrowOnFailure(hr, L"Failed to unregister bundle."); 265 TestThrowOnFailure(hr, L"Failed to unregister bundle.");
264 266
265 // verify that registration was removed 267 // verify that registration was removed
@@ -301,6 +303,7 @@ namespace Bootstrapper
301 BURN_CACHE cache = { }; 303 BURN_CACHE cache = { };
302 BURN_ENGINE_COMMAND internalCommand = { }; 304 BURN_ENGINE_COMMAND internalCommand = { };
303 String^ cacheDirectory = Path::Combine(Path::Combine(Environment::GetFolderPath(Environment::SpecialFolder::LocalApplicationData), gcnew String(L"Package Cache")), gcnew String(TEST_BUNDLE_ID)); 305 String^ cacheDirectory = Path::Combine(Path::Combine(Environment::GetFolderPath(Environment::SpecialFolder::LocalApplicationData), gcnew String(L"Package Cache")), gcnew String(TEST_BUNDLE_ID));
306 DWORD dwRegistrationOptions = 0;
304 try 307 try
305 { 308 {
306 // set mock API's 309 // set mock API's
@@ -350,7 +353,7 @@ namespace Bootstrapper
350 // 353 //
351 354
352 // write registration 355 // write registration
353 hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &cache, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, 0, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS); 356 hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &cache, &variables, dwRegistrationOptions, 0, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS);
354 TestThrowOnFailure(hr, L"Failed to register bundle."); 357 TestThrowOnFailure(hr, L"Failed to register bundle.");
355 358
356 // verify that registration was created 359 // verify that registration was created
@@ -358,7 +361,7 @@ namespace Bootstrapper
358 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.clean.room /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr)); 361 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.clean.room /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr));
359 362
360 // complete registration 363 // complete registration
361 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_ARP, BOOTSTRAPPER_APPLY_RESTART_REQUIRED, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_FULL); 364 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_ARP, BOOTSTRAPPER_APPLY_RESTART_REQUIRED, BOOTSTRAPPER_REGISTRATION_TYPE_FULL);
362 TestThrowOnFailure(hr, L"Failed to unregister bundle."); 365 TestThrowOnFailure(hr, L"Failed to unregister bundle.");
363 366
364 // verify that registration variables were updated 367 // verify that registration variables were updated
@@ -378,7 +381,7 @@ namespace Bootstrapper
378 // 381 //
379 382
380 // delete registration 383 // delete registration
381 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_NONE); 384 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BOOTSTRAPPER_REGISTRATION_TYPE_NONE);
382 TestThrowOnFailure(hr, L"Failed to unregister bundle."); 385 TestThrowOnFailure(hr, L"Failed to unregister bundle.");
383 386
384 // verify that registration was removed 387 // verify that registration was removed
@@ -420,6 +423,7 @@ namespace Bootstrapper
420 BURN_CACHE cache = { }; 423 BURN_CACHE cache = { };
421 BURN_ENGINE_COMMAND internalCommand = { }; 424 BURN_ENGINE_COMMAND internalCommand = { };
422 String^ cacheDirectory = Path::Combine(Path::Combine(Environment::GetFolderPath(Environment::SpecialFolder::LocalApplicationData), gcnew String(L"Package Cache")), gcnew String(TEST_BUNDLE_ID)); 425 String^ cacheDirectory = Path::Combine(Path::Combine(Environment::GetFolderPath(Environment::SpecialFolder::LocalApplicationData), gcnew String(L"Package Cache")), gcnew String(TEST_BUNDLE_ID));
426 DWORD dwRegistrationOptions = 0;
423 try 427 try
424 { 428 {
425 // set mock API's 429 // set mock API's
@@ -471,7 +475,7 @@ namespace Bootstrapper
471 // 475 //
472 476
473 // write registration 477 // write registration
474 hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &cache, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, 0, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS); 478 hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &cache, &variables, dwRegistrationOptions, 0, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS);
475 TestThrowOnFailure(hr, L"Failed to register bundle."); 479 TestThrowOnFailure(hr, L"Failed to register bundle.");
476 480
477 // verify that registration was created 481 // verify that registration was created
@@ -479,7 +483,7 @@ namespace Bootstrapper
479 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.clean.room /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr)); 483 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.clean.room /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr));
480 484
481 // finish registration 485 // finish registration
482 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_ARP, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_FULL); 486 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_ARP, BOOTSTRAPPER_APPLY_RESTART_NONE, BOOTSTRAPPER_REGISTRATION_TYPE_FULL);
483 TestThrowOnFailure(hr, L"Failed to register bundle."); 487 TestThrowOnFailure(hr, L"Failed to register bundle.");
484 488
485 // verify that registration was updated 489 // verify that registration was updated
@@ -504,7 +508,7 @@ namespace Bootstrapper
504 // 508 //
505 509
506 // write registration 510 // write registration
507 hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &cache, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, 0, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS); 511 hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &cache, &variables, dwRegistrationOptions, 0, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS);
508 TestThrowOnFailure(hr, L"Failed to register bundle."); 512 TestThrowOnFailure(hr, L"Failed to register bundle.");
509 513
510 // verify that registration was updated 514 // verify that registration was updated
@@ -512,7 +516,7 @@ namespace Bootstrapper
512 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.clean.room /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr)); 516 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.clean.room /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr));
513 517
514 // delete registration 518 // delete registration
515 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_NONE); 519 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BOOTSTRAPPER_REGISTRATION_TYPE_NONE);
516 TestThrowOnFailure(hr, L"Failed to unregister bundle."); 520 TestThrowOnFailure(hr, L"Failed to unregister bundle.");
517 521
518 // verify that registration was removed 522 // verify that registration was removed
@@ -558,6 +562,7 @@ namespace Bootstrapper
558 BURN_ENGINE_COMMAND internalCommand = { }; 562 BURN_ENGINE_COMMAND internalCommand = { };
559 BYTE* pbBuffer = NULL; 563 BYTE* pbBuffer = NULL;
560 SIZE_T cbBuffer = 0; 564 SIZE_T cbBuffer = 0;
565 DWORD dwRegistrationOptions = 0;
561 566
562 String^ cacheDirectory = Path::Combine(Path::Combine(Environment::GetFolderPath(Environment::SpecialFolder::LocalApplicationData), gcnew String(L"Package Cache")), gcnew String(TEST_BUNDLE_ID)); 567 String^ cacheDirectory = Path::Combine(Path::Combine(Environment::GetFolderPath(Environment::SpecialFolder::LocalApplicationData), gcnew String(L"Package Cache")), gcnew String(TEST_BUNDLE_ID));
563 try 568 try
@@ -614,7 +619,7 @@ namespace Bootstrapper
614 TestThrowOnFailure(hr, L"Failed to get current process path."); 619 TestThrowOnFailure(hr, L"Failed to get current process path.");
615 620
616 // begin session 621 // begin session
617 hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &cache, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, 0, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS); 622 hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &cache, &variables, dwRegistrationOptions, 0, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS);
618 TestThrowOnFailure(hr, L"Failed to register bundle."); 623 TestThrowOnFailure(hr, L"Failed to register bundle.");
619 624
620 VariableSetNumericHelper(&variables, L"MyBurnVariable1", 42); 625 VariableSetNumericHelper(&variables, L"MyBurnVariable1", 42);
@@ -657,7 +662,7 @@ namespace Bootstrapper
657 NativeAssert::StringEqual(L"42", sczValue); 662 NativeAssert::StringEqual(L"42", sczValue);
658 663
659 // end session 664 // end session
660 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_NONE); 665 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BOOTSTRAPPER_REGISTRATION_TYPE_NONE);
661 TestThrowOnFailure(hr, L"Failed to unregister bundle."); 666 TestThrowOnFailure(hr, L"Failed to unregister bundle.");
662 } 667 }
663 finally 668 finally
@@ -700,6 +705,7 @@ namespace Bootstrapper
700 SIZE_T cbBuffer = 0; 705 SIZE_T cbBuffer = 0;
701 SIZE_T piBuffer = 0; 706 SIZE_T piBuffer = 0;
702 String^ cacheDirectory = Path::Combine(Path::Combine(Environment::GetFolderPath(Environment::SpecialFolder::LocalApplicationData), gcnew String(L"Package Cache")), gcnew String(TEST_BUNDLE_ID)); 707 String^ cacheDirectory = Path::Combine(Path::Combine(Environment::GetFolderPath(Environment::SpecialFolder::LocalApplicationData), gcnew String(L"Package Cache")), gcnew String(TEST_BUNDLE_ID));
708 DWORD dwRegistrationOptions = 0;
703 try 709 try
704 { 710 {
705 // set mock API's 711 // set mock API's
@@ -758,7 +764,7 @@ namespace Bootstrapper
758 Assert::Equal((int)BOOTSTRAPPER_RESUME_TYPE_NONE, (int)resumeType); 764 Assert::Equal((int)BOOTSTRAPPER_RESUME_TYPE_NONE, (int)resumeType);
759 765
760 // begin session 766 // begin session
761 hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &cache, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, 0, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS); 767 hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &cache, &variables, dwRegistrationOptions, 0, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS);
762 TestThrowOnFailure(hr, L"Failed to register bundle."); 768 TestThrowOnFailure(hr, L"Failed to register bundle.");
763 769
764 VariableSetNumericHelper(&variables, L"MyBurnVariable1", 42); 770 VariableSetNumericHelper(&variables, L"MyBurnVariable1", 42);
@@ -797,7 +803,7 @@ namespace Bootstrapper
797 Assert::Equal((int)BOOTSTRAPPER_RESUME_TYPE_INTERRUPTED, (int)resumeType); 803 Assert::Equal((int)BOOTSTRAPPER_RESUME_TYPE_INTERRUPTED, (int)resumeType);
798 804
799 // suspend session 805 // suspend session
800 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_SUSPEND, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS); 806 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_SUSPEND, BOOTSTRAPPER_APPLY_RESTART_NONE, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS);
801 TestThrowOnFailure(hr, L"Failed to suspend session."); 807 TestThrowOnFailure(hr, L"Failed to suspend session.");
802 808
803 // verify that run key was removed 809 // verify that run key was removed
@@ -824,7 +830,7 @@ namespace Bootstrapper
824 Assert::NotEqual((Object^)nullptr, Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr)); 830 Assert::NotEqual((Object^)nullptr, Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr));
825 831
826 // end session 832 // end session
827 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_NONE); 833 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BOOTSTRAPPER_REGISTRATION_TYPE_NONE);
828 TestThrowOnFailure(hr, L"Failed to unregister bundle."); 834 TestThrowOnFailure(hr, L"Failed to unregister bundle.");
829 835
830 // read resume type after session 836 // read resume type after session